专栏首页码农小胖哥的码农生涯Java 快速开发二维码生成服务

Java 快速开发二维码生成服务

1. 前言

不知道从什么时候开始,我们的生活突然之间就充满了二维码,连街边大妈的鸡蛋饼早餐摊也贴上了二维码。而且这次疫情的管控也用上了二维码,避免手工填写造成交叉感染。那么 Java 如何开发二维码功能呢?今天来简单探讨一下。欢迎加入微信圈子程序员交流圈 交流编程经验,欢迎投稿。

2. 关于二维码

作为开发者我们肯定会想到二维码是将内容编码成了二维码的图案。对于其原理我们并不需要知道,就是一个编码和解码的过程。但是我们开发中还是需要知道了解一些关于二维码的东西:

  • 完全相同的二维码在算法一致的前提下内容完全相同,反之不成立。
  • 内容越多二维码越复杂,这可以从二维码的图像上肉眼可见。意味着解码就越耗时。
  • 二维码有容错率,容错率越高意味着二维码包含的信息量越大。

根据以上的几点,我们在开发中根据实际情况来作出一些调整,后面会来讲一下我自己的经验。

3. Java 实现二维码的生成

通常我们使用 Google 开源的 1D/2D 条码图像处理库 ZXing 来实现。我们可以通过引入其依赖来集成二维码生成功能:

   <dependency>
       <groupId>com.google.zxing</groupId>
       <artifactId>core</artifactId>
       <version>3.4.0</version>
   </dependency>
   <dependency>
       <groupId>com.google.zxing</groupId>
       <artifactId>javase</artifactId>
       <version>3.4.0</version>
   </dependency>

然后我们可以通过下面短短几行代码就生成了一个二维码并将其保存到本地:

QRCodeWriter qrCodeWriter = new QRCodeWriter();
# 第一个参数为二维码的内容 第二个参数不变  第三 四 个参数依次为 宽高
BitMatrix bitMatrix = qrCodeWriter.encode("https://www.felord.cn", BarcodeFormat.QR_CODE, 30, 30);
# 将二维码保存为 png 本地图片。
MatrixToImageWriter.writeToPath(encode, "png", Paths.get("E:\\workbase\\qr.png"));

如果你要控制编码的字符集和纠错率,上面的代码可更改为:

QRCodeWriter qrCodeWriter = new QRCodeWriter();
Map<EncodeHintType, Object> hints = new HashMap<>();
   hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
   hints.put(EncodeHintType.CHARACTER_SET,"UTF-8");
BitMatrix bitMatrix = qrCodeWriter.encode("https://www.felord.cn", BarcodeFormat.QR_CODE, 80, 80,hints);
# 将二维码保存为 png 本地图片。
MatrixToImageWriter.writeToPath(encode, "png", Paths.get("E:\\workbase\\qr.png"));

其实 MatrixToImageWriter 不但提供将二维码保存为文件,还可以转化为流:

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
MatrixToImageWriter.writeToStream(bitMatrix,"png",byteArrayOutputStream);

byte[] bytes = byteArrayOutputStream.toByteArray();
String base64Image = new BASE64Encoder().encode(bytes);

生成的 base64Image 我们可以在前端通过以下方式进行展示:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABQAQAAAACmas8AAAAAvklEQVR42tXSsRGDMAwFUKWxV0jl
rGY39gpOg6BxVoDGWQ0aewVorOQOzgeCARJVr9G/rzsB1YEfZgHh5QjIiPn1zoVTu6SsOLPIdMEh
2BMxJ1lzK0FYq4GRqJgWt76V5e665Na1HQ1F09/oSIpu6qaIRxaztG5pOZXrmy1sRzPjqJ7EKIQ2
Ye27o8clD4ETJxrB0JHfg7xqOAvIrtgGGTFH3XhObS3ABTHn+UQXXAROTI88a04QGB6R8Q9e+QOH
lnNzjaH0oAAAAABJRU5ErkJggg=="  alt="">

Base64 展示体积小的二维码是没有问题的,如果生成的 Base64 字符串比较长将会有较大的渲染消耗。实际生产中要权衡利弊。

4. 动态二维码

如果我们需要动态的来生成二维码,或者换句话来说将二维码作为服务。我们可以借助于 Servlet 来实现一个动态的二维码服务。我们使用 Spring MVC 来实现:

package cn.felord.qr.format;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author dax
 * @since 2020/2/29 21:09
 */
@Controller
@RequestMapping("/qr")
public class QRController {

    @GetMapping("/felord")
   public void gen(HttpServletResponse response) throws IOException, WriterException {

       response.setContentType("image/png");
       ServletOutputStream outputStream = response.getOutputStream();
       outputStream.write(imageBytes());
       outputStream.flush();
       outputStream.close();
   }


   private byte [] imageBytes() throws IOException, WriterException {
       QRCodeWriter qrCodeWriter = new QRCodeWriter();

       Map<EncodeHintType, Object> hints = new HashMap<>();
       hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
       hints.put(EncodeHintType.CHARACTER_SET,"UTF-8");

       BitMatrix bitMatrix = qrCodeWriter.encode("https://www.felord.cn", BarcodeFormat.QR_CODE, 80, 80,hints);

       ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
       MatrixToImageWriter.writeToStream(bitMatrix,"png",byteArrayOutputStream);
      return byteArrayOutputStream.toByteArray();
   }

}

5. 一些实践中的经验

在实际生产中我们要注意以下几点:

  • 尽量避免在二维码中传递敏感的明文信息,应对其进行摘要处理或者脱敏。
  • 对于比较长的网址应该使用短网址服务以减少二维码的信息载荷。
  • 尽量保证二维码一定时间内的唯一性,比如加一些无意义随机值等。
  • 其实也有其它一些功能强大开箱即用的的 zxing 二次封装库可用,比如 qrext4j

6. 总结

今天就 Java 开发二维码功能进行了一些探讨,从二维码的一些特点到 ZXing 生成二维码并开发为服务,最后还对实际使用中的一些要点进行了罗列,希望对你有用。

本文分享自微信公众号 - 码农小胖哥(Felordcn),作者:码农小胖哥

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-02-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • mysql如何进行累加计算

    接了一个需求,产品想分析一下用户增长的曲线。也就是某个时间段的每日总人数列表。好对近期活动进行一个效果的评测。这个统计sql还是花了我一小段时间的。mysql统...

    码农小胖哥
  • Windows 命令行终端 PowerShell 美化计划

    作为一个程序员,终端工具是必不可少的。但是「Windows」 的默认终端实在太丑了,作为一个颜控忍不了。所以必须实施终端改造计划。目前我们都会使用 「Power...

    码农小胖哥
  • Java开发中如何自动填充SQL语句中的公共字段

    我们在设计数据库的时候一定会带上新增、更新的时间、操作者等审计信息。之所以带这些信息是因为假如有一天公司的数据库被人为删了,尽管可能有数据库备份可以恢复数据。但...

    码农小胖哥
  • 在二维码生成软件中如何生成PDF417二维码

    Pdf417码,是二维码中比较特殊的码制,可以用来表示数字、字母、汉字或二进制数据。PDF417码最大的特点是信息容量大,纠错能力强,印刷要求不高,普通打印设备...

    用户5746110
  • 一行python代码生成酷炫/恶搞/表白二维码(内附源码)

    很多人都扫过二维码,大部分人的印象都是黑白相间的小方块,实际上二维码是运用了计算机图像处理技术,组合编码原理的一种编码,其用黑白像素点的图像来代表二进制中的“1...

    行哥玩Python
  • 还可以这样玩!一键生成「专属二维码」,就靠这 4 款小程序

    今天,知晓程序(微信号 zxcx0101)给你推荐 4 款二维码生成器小程序,让你轻松玩转二维码。

    知晓君
  • 5 行 Python 代码生成自定义二维码

    随着互联网和智能移动设备不断普及,二维码(Quick Response code)已经成为世界上应用最为广泛的信息载体之一。生成二维码的工具也层出不穷,但多数需...

    用户2769421
  • 走近科学:二维码真的安全吗

    二维码自普及以来,无论是从它的便捷性,还是其安全问题,一直都是公众关注的焦点问题。“码”时代来势迅猛,不可阻挡,似乎一夜之间,二维码即遍布各电商平台、商场、网站...

    FB客服
  • 二维码会使用完么?

    现在生活中总是会使用到二维码,在支付中、博客的推广图片上、各种各样的商品推广,都有着二维码的身影,二维码已经是我们的日常生活中有着不可替代的便捷信息载体,近几日...

    Debug客栈
  • Excel也能制作二维码

    现在二维码广泛流行,各种各样的地方都需要扫码。二维码不光能使用代码来实现,也可以通过Excel来制作二维码。

    一觉睡到小时候

扫码关注云+社区

领取腾讯云代金券