Spring Boot 生成二维码并下载 ,这其实是无线网络与物联网技术老师布置的作业,任选一门语言生成二维码,于是乎查了一下资料用spring 框架写了这个 Spring Boot 生成二维码并下载 的 小demo。
地址
预览


依赖下载
由于我使用的是QRCode.jar依赖,并且无法在自己的maven仓库里面下载,点击下面的按钮下载jar包,然后手动导入即可。
核心代码
CreateQRCode.class
首先是生成二维码的工具类,CreateQRCode.class,这一核心代码主要参考了bigroc 的博文,最后我会给出原文地址。原作者的是java 生成二维码到本地,我改用spring boot 使之成为了web应用并实现了二维码的下载功能。
public class CreateQRCode {
//读取配置文件
@Value("${view.path}")
private String webpath;
@Value("${real.path}")
private String realpath;
public Object CreataQRCode(String data, HttpServletRequest request ) throws IOException {
//计算二维码图片的高宽比
// API文档规定计算图片宽高的方式 ,v是本次测试的版本号
int v =7;
int width = 67 + 12 * (v - 1);
int height = 67 + 12 * (v - 1);
Qrcode x = new Qrcode();
/**
* 纠错等级分为
* level L : 最大 7% 的错误能够被纠正;
* level M : 最大 15% 的错误能够被纠正;
* level Q : 最大 25% 的错误能够被纠正;
* level H : 最大 30% 的错误能够被纠正;
*/
x.setQrcodeErrorCorrect('L');
x.setQrcodeEncodeMode('B');//注意版本信息 N代表数字 、A代表 a-z,A-Z、B代表 其他)
x.setQrcodeVersion(v);//版本号 1-40
String qrData = data;//内容信息
byte[] d = qrData.getBytes("utf-8");//汉字转格式需要抛出异常
//缓冲区
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
//绘图
Graphics2D gs = bufferedImage.createGraphics();
gs.setBackground(Color.WHITE);
gs.setColor(Color.BLACK);
gs.clearRect(0, 0, width, height);
//偏移量
int pixoff = 2;
/**
* 容易踩坑的地方
* 1.注意for循环里面的i,j的顺序,
* s[j][i]二维数组的j,i的顺序要与这个方法中的 gs.fillRect(j*3+pixoff,i*3+pixoff, 3, 3);
* 顺序匹配,否则会出现解析图片是一串数字
* 2.注意此判断if (d.length > 0 && d.length < 120)
* 是否会引起字符串长度大于120导致生成代码不执行,二维码空白
* 根据自己的字符串大小来设置此配置
*/
if (d.length > 0 && d.length < 120) {
boolean[][] s = x.calQrcode(d);
for (int i = 0; i < s.length; i++) {
for (int j = 0; j < s.length; j++) {
if (s[j][i]) {
gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3, 3);
}
}
}
}
gs.dispose();
bufferedImage.flush();
//设置图片格式,与输出的路径
String pathName=System.currentTimeMillis()+".png";
ImageIO.write(bufferedImage, "png", new File(realpath+pathName));
//拼接图片web访问路径
String webPath=webpath+pathName;
JSONObject result = new JSONObject();
result.put("status",200);
result.put("filename",pathName);
result.put("url",webPath);
result.put("message","生成成功");
return result;
}
}
ApiController.class
这一部分主要是处理前端的生成和下载二维码两个请求。
public class ApiController {
@Autowired
private CreateQRCode createQRCode;
@Value("${server.path}")
private String serverPath;
@Value("${view.path}")
private String webPath;
@RequestMapping("/api/generateCode")
@ResponseBody
public Object generateCode(@RequestBody JSONObject object, HttpServletRequest request) throws IOException {
String string = object.get("string").toString();
JSONObject result = (JSONObject) createQRCode.CreataQRCode(string, request);
if (result.getInteger("status") == 200) return result;
else {
JSONObject error = new JSONObject();
error.put("status", 100);
error.put("message", "未知错误");
return error;
}
}
@RequestMapping("/api/download/{filename}")
public Object downloadQRCode(@PathVariable("filename") String fileName, HttpServletResponse response, HttpServletRequest request) {
String path = request.getServletPath();
System.out.println(path);
String URL = serverPath+webPath+fileName;
InputStream inputStream = null;
HttpURLConnection httpURLConnection = null;
ServletOutputStream outputStream = null;
try {
URL url = new URL(URL);
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setConnectTimeout(3000);
httpURLConnection.setDoInput(true);
httpURLConnection.setRequestMethod("GET");
int responseCode = httpURLConnection.getResponseCode();
response.setContentType("application/x-download");
response.addHeader("Content-Disposition","attachment;filename=" + fileName);
if (responseCode == 200) {
inputStream =httpURLConnection.getInputStream();
outputStream = response.getOutputStream();
// 在http响应中输出流
byte[] cache = new byte[1024];
int nRead = 0;
while ((nRead = inputStream.read(cache) ) != -1) {
outputStream.write(cache, 0, nRead);
}
outputStream.flush();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
前端
最后就是前端HTML代码了,虽然一开始打算利用thymeleaf模板引擎优化,后来为了快速完成就没有用到thmeleaf语法了。一开始前端完全是由我自己写的,但是毕竟不是专业的前端,不太美观并且也没有响应式,后来在html5 up下载的模板修改了一下并使用,整体看起来美观了一些。
<!DOCTYPE HTML>
<html>
<head>
<title>二维码在线生成</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<link rel="icon" type="image/x-icon" href="https://yremp.live/wp-content/uploads/2019/09/logo-04-e1567837918204.png">
<link rel="stylesheet" href="assets/css/main.css" />
<link href="https://cdn.bootcss.com/font-awesome/5.12.1/css/all.css" rel="stylesheet">
<noscript><link rel="stylesheet" href="assets/css/noscript.css" /></noscript>
</head>
<body class="is-preload">
<!-- Wrapper -->
<div id="wrapper">
<!-- Main -->
<section id="main">
<header>
<span class="avatar"><img id="avatar" src="https://cdn.jsdelivr.net/gh/yremp/resource@2.0/img/custom/head.jpg" alt="" /></span>
<h1>Yremp</h1>
<p>二维码在线生成</p>
</header>
<hr />
<div class="fields">
<div class="field">
<input type="text" name="name" id="info" placeholder="QRCOde Information" />
</div>
<br>
<ul class="actions special">
<li ><a href="#" id="start-btn" class="button" onclick="generate()">Get QRCode</a></li>
</ul>
<hr />
<footer>
<li style="list-style: none"><a id="down-btn" href="#" data="" class="button" >Download QRCode</a></li>
</footer>
</section>
<!-- Footer -->
<footer id="footer">
<ul class="copyright">
<li>© Yremp</li><li>Site: <a href="https://yremp.live">yremp.live</a></li><li>Theme By: <a href="https://html5up.net/"> HTML5 UP</a> </li>
</ul>
</footer>
</div>
<!-- Scripts -->
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script src="/layer/layer.js"></script>
<script>
if ('addEventListener' in window) {
window.addEventListener('load', function() { document.body.className = document.body.className.replace(/\bis-preload\b/, ''); });
document.body.className += (navigator.userAgent.match(/(MSIE|rv:11\.0)/) ? ' is-ie' : '');
}
var layer;
function generate() {
var data = $("#info").val();
var list = {
string: data
};
if(data==null||data==''){
layer.msg("请输入二维码内容!",{icon:2})
return null;
}
$.ajax({
type: "POST",
contentType: "application/json;charset=UTF-8",
url: "/api/generateCode",
data: JSON.stringify(list),
success: function (res) {
console.log(list);
console.log(res);
if (res.status === 200) {
layer.msg(res.message, {icon: 1});
$("#avatar").attr("src",res.url);
$("#down-btn").attr("href","/api/download/"+res.filename);
$("#avatar").addClass("code");
} else {
}
}
})
}
</script>
</body>
</html>
感谢
感谢bigroc提供的参考代码,原文地址: https://www.cnblogs.com/bigroc/p/7496995.html
标签云
ajax AOP Bootstrap cdn Chevereto CSS Docker Editormd GC Hexo IDEA IPA JavaScript jsDeliver JS樱花特效 JVM Linux markdown Maven MyBatis MyBatis-plus MySQL Pictures Sakura SEO shadowrocket Spring Boot Spring Cloud Spring Cloud Alibaba SpringMVC SSR Thymeleaf V2ray Vue Web WebSocket Wechat Social WordPress Yoast SEO 代理 分页 图床 小幸运 苹果iOS国外账号 苹果IOS账号
Comments | 8 条评论
把springboot打war包放入tomcat中,还要看他的配置文件的端口吗,不需要吧
@燚人 你的tomcat是在本地电脑还是服务器?或者你去主页加一下我QQ,看看报错吧
@Yremp 你主页QQ没法扫
@Yremp 扫到了
本地测试正常,就tomcat部署出现问题controller里面/api/generateCode的路径一直404
@燚人 可能是配置文件application.properties 指定的端口问题,你排查一下吧 。
你好,我想放到tomcat里面一直出问题This application has no explicit mapping for /error…,该怎么改
@燚人 你先测试在本地运行情况吧