利用hutool生成二维码并返回

392 阅读2分钟

最近有点想做一个功能:生成海报图,海报图要求有海报标题、海报介绍和链接二维码,标题和介绍很简单,就是二维码需要使用接口生成。像这种简单的功能我自然不会使用第三方接口,于是准备自己写一个出来。

构思

这个接口很简单,传入url(必填),width(选填),height(选填),然后返回一个二维码图片。由于之前使用了一个hutool的第三方工具依赖,于是去官网查看是否可以生成二维码,如果不行的话,就手动来写一个。

资料

好在hutool封装了生成二维码的方法,不用自己手动去写了,相关信息:doc.hutool.cn/pages/QrCod…

这文档看到一半有点不开心了,全是将二维码保存在本地的,不过幸好我抱着试一试的态度,发现其功能远不止教程上所写的那些。

过程

添加依赖

在pom文件中要除hutool依赖以外另外添加一个zxing的依赖,印象当中这是谷歌的开发的,之前在Android开发中有用到过,跑题了,添加依赖:

<!-- hutool工具-->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.3</version>
</dependency>
<!-- 二维码工具 -->
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>3.3.3</version>
</dependency>

编写接口

在controller中新增一个接口 createQRCode 并在对应的service中新增实现方法:

    // 生成url二维码
    @GetMapping("/createQRCode")
    public void createQRCode(HttpServletResponse response, @RequestParam String url, @RequestParam(defaultValue = "300") int width, @RequestParam(defaultValue = "300") int height) {
        iCommonAPIService.createQRCode(response, url, width, height);
    }

这里要注意一点:这是一个 void 方法,切记!如果是其他类型的方法,可能会导致报错:

No converter for [class java.awt.image.BufferedImage] with preset Content-Type 'image/jpeg'

具体实现

实现非常简单,利用 QrCodeUtil.generate 生成二维码后,利用 ServletOutputStream返回图片即可。

ps. Springboot中BufferedImage不可以直接返回。

@SneakyThrows
@Override
public void createQRCode(HttpServletResponse response, String url, int width, int height) {
    response.setDateHeader("Expires", 0);
    // Set standard HTTP/1.1 no-cache headers.
    response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
    // Set IE extended HTTP/1.1 no-cache headers (use addHeader).
    response.addHeader("Cache-Control", "post-check=0, pre-check=0");
    // Set standard HTTP/1.0 no-cache header.
    // return a jpeg
    response.setContentType("image/jpeg");
    BufferedImage generate = QrCodeUtil.generate(url, new QrConfig(width,height));
    ServletOutputStream out = response.getOutputStream();
    // write the data out
    ImageIO.write(generate, "jpg", out);
    try {
        out.flush();
    } finally {
        out.close();
    }
}

结果

访问接口:

image.png