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

地址

  1. 演示地址
  2. Github项目地址

预览

首页
生成二维码

依赖下载

由于我使用的是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 Github Hexo IDEA JavaScript jsDeliver JS樱花特效 JVM Linux Live2D markdown Maven MyBatis MyBatis-plus MySQL Navicat Oracle Pictures QQ Sakura SEO Spring Boot Spring Cloud Spring Cloud Alibaba SpringMVC Thymeleaf Vue Web WebSocket Wechat Social WordPress Yoast SEO 代理 分页 图床 小幸运 通信原理