Java 快速開發二維碼生成服務

2021-02-14 碼農小胖哥
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 二次封裝庫可用,比如 qrext4j6. 總結

今天就 Java 開發二維碼功能進行了一些探討,從二維碼的一些特點到 ZXing 生成二維碼並開發為服務,最後還對實際使用中的一些要點進行了羅列,希望對你有用。歡迎通過留言發表你的看法和疑問。更多精彩文章可通過公眾號分類菜單獲取。

相關焦點

  • Java生成二維碼
    本例演示如何在一個非 android 的 Java 項目中使用 ZXing 來生成、解析二維碼圖片。2. com.google.zxing.client.j2se.MatrixToImageWriter 根據圖像矩陣生成圖片文件或圖片緩存 BufferedImage 。
  • Java 生成二維碼實戰
    p=5051不知道從什麼時候開始,我們的生活突然之間就充滿了二維碼——看網頁要掃二維碼,加好友要掃二維碼,現在連樓下賣草莓的大爺都支持掃碼支付了。其實在我們介紹二維碼的原理之前,你可能已經猜到了,二維碼就是把信息翻譯成黑白小方塊,然後填到這個大方塊裡。
  • Java生成、解析二維碼(附源碼)
    大家好,我是鴨哥。
  • 如何使用 Java 生成二維碼?
    編寫實體類實現二維碼的生成4. controller調用1.下載jar包(QRCode.jar)下載網址如下: QRCode生成二維碼網址:http://swetake.com/qrcode/index-e.html2. maven項目手動引入jar包mvn install:install-file-DgroupId=包名-DartifactId=項目名-Dversion=版本號-Dpackaging
  • 如何在線生成二維碼?
    在實際的業務開發過程中,二維碼的使用場景開發也會經常出現在我們開發人員的面前,我們應該如何去處理呢,今天小編就帶著大家一起深入的了解一下它的技術實現過程。如何快速生成二維碼呢?;import java.io.File;import java.util.Date;import java.util.HashMap;import java.util.Map;/** * * 二維碼、條形碼工具類 */public class QRCodeWriteUtil {    /**
  • 聽說 Python 生成二維碼很簡單,說的好像我Java 很複雜一樣.
    今天阿粉就教給大家來生成一個小小的二維碼,而且也是一樣的簡單。是用某種特定的幾何圖形按一定規律在平面(二維方向上)分布的、黑白相間的、記錄數據符號信息的圖形;QR來自英文「Quick Response」的縮寫,即快速反應的意思,源自發明者希望QR碼可讓其內容快速被解碼而阿粉帶給大家的jar
  • 【二維碼生成器】快速生成個性二維碼
    用這款精美的二維碼生成器,您可以輕鬆地生成好看又獨特的二維碼。 這款二維碼製作器可以自定義二維碼的顏色,碼點,碼陣。您還可以添加logo和文本,來讓您的二維碼更加好看和特別。你不僅可以製作彩色二維碼,最香的是,你甚至可以使用由設計師設計的精美模板直接生成二維碼,讓二維碼製作這件事情變得簡單快捷!嘗試一下!用這款二維碼生成器來創造出人見人誇,人見人掃的二維碼吧!
  • 如何使用Java、Servlet創建二維碼
    歸功於智慧型手機,QR碼逐漸成為主流,它們正變得越來越有用。從候車亭、產品包裝、家裝賣場、汽車到很多網站,都在自己的網頁集成QR碼,讓人們快速找到它們。隨著智慧型手機的用戶量日益增長,二維碼的使用正在呈指數上升。讓我們來看看QR碼的簡要概述,以及如何在Java中生成它們。
  • 六步教你學會用Java生成二維碼
    package imis.black.zxing;import java.io.File;import java.nio.file.Path;import java.util.HashMap;import com.google.zxing.BarcodeFormat;import com.google.zxing.EncodeHintType
  • Springboot + zwing 二維碼生成回顯
    本篇文章給大家帶來的是 Springboot + zwing 二維碼生成回顯我們大家都知道這個二維碼哈,但是並沒有人知道這個二維碼是如何去生成的
  • 【SpringBoot】SpringBoot生成二維碼
    二維碼是用某種特定的幾何圖形按一定規律在平面(二維方向上)分布的黑白相間的圖形記錄數據符號信息的。信息獲取(名片、地圖、WIFI密碼、資料)網站跳轉(跳轉到微博、手機網站、網站)廣告推送(用戶掃碼,直接瀏覽商家推送的視頻、音頻廣告)手機電商(用戶掃碼、手機直接購物下單)防偽溯源(用戶掃碼、即可查看生產地;同時後臺可以獲取最終消費地)優惠促銷(用戶掃碼,下載電子優惠券,抽獎)會員管理(用戶手機上獲取電子會員信息、VIP服務
  • Java生成PDF
    如題,在日常的項目開發中,我們會遇到需要通過Java代碼生成pdf,本文主要介紹的是通過velocity模板生產pdf。我們利用springboot可以快速開發項目,因為本文是採用的eclipse作為開發工具,直接打開官網進行項目的配置下載。下載下來的基本結構是如下圖:接下來我們修改pom.xml文件,引入需要的相關包。
  • 幾行代碼,輕鬆帶你實現Java生成二維碼功能!
    --生成二維碼--><dependency>  <groupId>com.google.zxing</groupId>  <artifactId>javase</artifactId>  <version>3.3.0</version></dependency>
  • java二維碼生成讀取
    二維碼再生活在無處不在,讓我們用最簡單的方法揭開二維碼的神秘面紗在開始之前,我們需要先引入二維碼生成和讀取的jar包,這裡我用的是
  • 一鍵生成二維碼,快速分享瀏覽器地址到手機
    abc=1&cdefg=2&hijk=33344 ……現在好了,只要我們有了 基於 Chrome 瀏覽器內核(幾乎是全部主流瀏覽器了)的插件, 就可以幫助我們「一鍵生成」網址二維碼。然後,我們只要手機對著屏幕掃碼,一切就都能解決了!
  • 二維碼生成源碼詳細講解教程
    import java.awt.Color;import java.awt.Graphics2D;import java.awt.Image;import java.awt.image.BufferedImage
  • 小程序生成二維碼
    需求一:二維碼信息固定,為了性能優化,一般會建議二維碼由服務端生成,然後前端返回二維碼的圖片,這樣,我們可以結合小程序的wx.previewimage()這個方法可以方便下載和預覽二維碼;需求二:動態生成二維碼信息,由於很多詳情頁面都需要根據頁面數據的參數動態生成二維碼,所以,這個時候可以前端完成二維碼生成,也可以服務端完成,但是對別人的依賴最後的結果就是自己的無奈
  • Vue前臺可以生成二維碼了,您還在用後臺生成嗎?
    Vue前臺可以生成二維碼和條形碼了,你還在用後臺嗎?
  • Excel催化劑功能第12波-快速生成、讀取、導出條形碼二維碼
    如果生成的二維碼條形碼,先進行排版一下列印出來,類似一個個標籤或用作相應的產品說明的一部分,那又是怎樣一種現成的解決方案呢?本次Excel催化劑再次刷新大家對Excel的認識,所有大家想做的事情,全部都在Excel內完成,藉助Excel快速地數據生成能力(函數公式Vlookup引用、數據填充等),快速得到條形碼、二維碼的原始數據,並藉助插件,一鍵完成條形碼、二維碼的生成、讀取、導出工作,極大地提升了日常的工作效率,無需額外定製購置軟體輔助完成!
  • 開源)嗨,Java,你可以生成金山詞霸的二維碼分享海報嗎?
    但不管是金山詞霸還是流利說,分享的海報都不是自己的二維碼,這對於個人品牌的締造者來說,實在是一件出力不討好的事。當然了,這種事難不倒作為程式設計師的我。這一篇文章我們就用 Java 來生成一下仿金山詞霸的海報。