User-Profile-Image
hankin
  • 5
  • Java
  • Kotlin
  • Spring
  • Web
  • SQL
  • MegaData
  • More
  • Experience
  • Enamiĝu al vi
  • 分类
    • Zuul
    • Zookeeper
    • XML
    • WebSocket
    • Web Notes
    • Web
    • Vue
    • Thymeleaf
    • SQL Server
    • SQL Notes
    • SQL
    • SpringSecurity
    • SpringMVC
    • SpringJPA
    • SpringCloud
    • SpringBoot
    • Spring Notes
    • Spring
    • Servlet
    • Ribbon
    • Redis
    • RabbitMQ
    • Python
    • PostgreSQL
    • OAuth2
    • NOSQL
    • Netty
    • MySQL
    • MyBatis
    • More
    • MinIO
    • MegaData
    • Maven
    • LoadBalancer
    • Kotlin Notes
    • Kotlin
    • Kafka
    • jQuery
    • JavaScript
    • Java Notes
    • Java
    • Hystrix
    • Git
    • Gateway
    • Freemarker
    • Feign
    • Eureka
    • ElasticSearch
    • Docker
    • Consul
    • Ajax
    • ActiveMQ
  • 页面
    • 归档
    • 摘要
    • 杂图
    • 问题随笔
  • 友链
    • Spring Cloud Alibaba
    • Spring Cloud Alibaba - 指南
    • Spring Cloud
    • Nacos
    • Docker
    • ElasticSearch
    • Kotlin中文版
    • Kotlin易百
    • KotlinWeb3
    • KotlinNhooo
    • 前端开源搜索
    • Ktorm ORM
    • Ktorm-KSP
    • Ebean ORM
    • Maven
    • 江南一点雨
    • 江南国际站
    • 设计模式
    • 熊猫大佬
    • java学习
    • kotlin函数查询
    • Istio 服务网格
    • istio
    • Ktor 异步 Web 框架
    • PostGis
    • kuangstudy
    • 源码地图
    • it教程吧
    • Arthas-JVM调优
    • Electron
    • bugstack虫洞栈
    • github大佬宝典
    • Sa-Token
    • 前端技术胖
    • bennyhuo-Kt大佬
    • Rickiyang博客
    • 李大辉大佬博客
    • KOIN
    • SQLDelight
    • Exposed-Kt-ORM
    • Javalin—Web 框架
    • http4k—HTTP包
    • 爱威尔大佬
    • 小土豆
    • 小胖哥安全框架
    • 负雪明烛刷题
    • Kotlin-FP-Arrow
    • Lua参考手册
    • 美团文章
    • Java 全栈知识体系
    • 尼恩架构师学习
    • 现代 JavaScript 教程
    • GO相关文档
    • Go学习导航
    • GoCN社区
    • GO极客兔兔-案例
    • 讯飞星火GPT
    • Hollis博客
    • PostgreSQL德哥
    • 优质博客推荐
    • 半兽人大佬
    • 系列教程
    • PostgreSQL文章
    • 云原生资料库
    • 并发博客大佬
Help?

Please contact us on our email for need any support

Support
    首页   ›   Java   ›   Java Notes   ›   正文
Java Notes

Java—快速开发二维码生成服务(ZXing)

2020-10-24 15:49:42
823  0 0
参考目录 隐藏
1) 1. 关于二维码
2) 2. Java 实现二维码的生成
3) 3. 动态二维码

阅读完需:约 5 分钟

不知道从什么时候开始,我们的生活突然之间就充满了二维码,连街边大妈的鸡蛋饼早餐摊也贴上了二维码。而且这次疫情的管控也用上了二维码,避免手工填写造成交叉感染。那么 Java 如何开发二维码功能呢?

1. 关于二维码

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

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

2. 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("http://www.enmalvi.com", BarcodeFormat.QR_CODE, 30, 30);
# 将二维码保存为 png 本地图片。
MatrixToImageWriter.writeToPath(bitMatrix, "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("http://www.enmalvi.com", BarcodeFormat.QR_CODE, 80, 80,hints);
# 将二维码保存为 png 本地图片。
MatrixToImageWriter.writeToPath(bitMatrix, "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 字符串比较长将会有较大的渲染消耗。实际生产中要权衡利弊。

3. 动态二维码

如果我们需要动态的来生成二维码,或者换句话来说将二维码作为服务。我们可以借助于 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;

@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();
   }

}

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

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

如本文“对您有用”,欢迎随意打赏作者,让我们坚持创作!

0 打赏
Enamiĝu al vi
不要为明天忧虑.因为明天自有明天的忧虑.一天的难处一天当就够了。
543文章 68评论 294点赞 593954浏览

随机文章
Redis笔记—Hash散列与Zset有序集合
5年前
Ajax——省市联动
5年前
Java—ThreadPoolExecutor/ThreadPoolTaskExecutor 线程池技术提高系统吞吐量
5年前
Java—并发编程(七)JUC集合 – (9) LinkedBlockingDeque
3年前
SpringBoot—扩展接口
2年前
博客统计
  • 日志总数:543 篇
  • 评论数目:68 条
  • 建站日期:2020-03-06
  • 运行天数:1927 天
  • 标签总数:23 个
  • 最后更新:2024-12-20
Copyright © 2025 网站备案号: 浙ICP备20017730号 身体没有灵魂是死的,信心没有行为也是死的。
主页
页面
  • 归档
  • 摘要
  • 杂图
  • 问题随笔
博主
Enamiĝu al vi
Enamiĝu al vi 管理员
To be, or not to be
543 文章 68 评论 593954 浏览
测试
测试
看板娘
赞赏作者

请通过微信、支付宝 APP 扫一扫

感谢您对作者的支持!

 支付宝 微信支付