点击上方蓝色“程序猿DD”,选择“设为星标”

回复“资源”获取独家整理的学习资料!

来源 | 公众号「码农小胖哥」

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

关注我,回复“加群”加入微信讨论群

  • Spring Boot 2.x:使用MyBatis访问MySQL

  • 最强摸鱼神器:开着IDEA看股票,看小说...

  • 真实版删库跑路,宕机36小时市值蒸发9亿!

  • 除了Postman之外,居然还有个Postwoman...

  • 实战 | 某小公司项目环境部署演变之路

推荐关注本文作者 码农小胖哥

朕已阅 

Java 快速开发二维码生成服务相关推荐

  1. 微信开发 -- 二维码生成

    微信开发 – 二维码生成 生成二维码无非就是将一段字符串内容以某种特定的方式进行编码, 最终得到一个图片. 这里使用 C# 生成二维码我用到了 QrCode.Net 这个 Nuget 包. 这里我们创 ...

  2. JAVA基础--QR_Code二维码生成

    2019独角兽企业重金招聘Python工程师标准>>> 项目中我们经常会用到二维码,今天就来讲讲二维码的生成: 1, 二维码的概念:            二维条码/二维码(2-di ...

  3. iOS开发二维码生成和扫描

    准备工作 导入<CoreImage/CoreImage.h>,生成二维码用 导入<AVFoundation/AVFoundation.h>,读取二维码用 设置代理协议AVCap ...

  4. iOS 开发 二维码生成大全(黑白/彩色二维码和带图片的二维码)详解

    前言 扫描二维码使用的是coreImage框架,属于UIKit框架中的体系,多以使用时不用导入coreImage框架 开始之前,让我们谈谈Core Image框架中最重要的几个类: CIContext ...

  5. iOS开发二维码生成(一)

    二维码是一种比一维码更高级的条码格式.一维码只能在一个方向(一般是水平方向)上表达信息,而二维码在水平和垂直方向都可以存储信息.一维码只能由数字和字母组成,而二维码能存储汉字.数字和图片等信息,因此二 ...

  6. java+vue的二维码生成,二维码上传服务器,二维码的压缩包下载

    一. vue页面生成二维码 <template><div class="app-container">//在页面放着二维码的div<div id=&q ...

  7. java实现二维码生成功能

    1.由来: 由于现在对二维码的使用比较多,正好我在项目里面也使用到了,所以写篇博客记录一下. 2.引入依赖: <dependency><groupId>com.google.z ...

  8. Android开发——Android中的二维码生成与扫描

    0. 前言 今天这篇文章主要描述二维码的生成与扫描,使用目前流行的Zxing,为什么要讲二维码,因为二维码太普遍了,随便一个Android APP都会有二维码扫描.本篇旨在帮助有需求的同学快速完成二维 ...

  9. zxing 二维码生成深度定制

    二维码生成服务之深度定制 之前写了一篇二维码服务定制的博文,现在则在之前的基础上,再进一步,花样的实现深度定制的需求,我们的目标是二维码上的一切都是可以由用户来随意指定 设计 1. 技术相关 zxin ...

最新文章

  1. 强化学习(七) - 函数近似方法 - 随机梯度下降, 半梯度下降,及瓦片编码(Tile Coding)实例
  2. mysql union 后 sum_mysql:多表查询
  3. 使用Tensorflow构建和训练自己的CNN来做简单的验证码识别
  4. 从路由原理出发,深入阅读理解react-router 4.0的源码
  5. troubleshoot之:用control+break解决线程死锁问题
  6. 【Python】urllib爬取动漫图片
  7. 程序员,软件测试知多少?
  8. IOS的IPV6测试
  9. pycharm直接显示所有show value的值(直接打开所有的值)
  10. lockdir.exe(文件夹加密软件)重装系统后打不开的解决办法
  11. 【信号与系统】z变换
  12. 批量将多个 txt 记事本文件合并成一个独立的记事本文件
  13. 线性代数————思维导图(上岸必备)(矩阵部分)
  14. 怎么修改服务器网卡mac地址是什么,网卡MAC地址是什么?怎么修改网卡MAC地址
  15. 关于设计BOM和制造BOM的介绍
  16. jquery boxy
  17. 苹果电脑可以装windows系统吗_给苹果电脑安装Windows系统
  18. Symbian 术语表
  19. 安装了两种oracle数据库怎么卸载,oracle数据库卸载步骤
  20. 2019 ICPC南昌网络赛 E题 Magic Master 【双向队列】

热门文章

  1. python3 检测端口是否开放
  2. linux c 线程同步的三种方法
  3. golang rune类型简介
  4. windows cmd命令行中 查看 修改 删除与添加环境变量
  5. linux docker 指定容器工作目录
  6. 零拷贝 zero-copy 原理
  7. python3 set 集合 简介
  8. linux centos 下载rpm源码包
  9. linux 僵尸进程 defunct
  10. msdn2010经典查看方式