通过本篇文章,你可以知道二维码怎样生成。
一、说明
二维码生成,就是将一个字符串变成二维码。当然这个字符串很多情况下是一个url。
为了生成二维码,我们需要 zing第三方类库
zing:
zing是一个开源的基于java的用来生成条形码的第三个类库
(ZXing (“zebra crossing”) is an open-source, multi-format 1D/2D barcode image processing library implemented in Java, with ports to other languages)
二、开始生成我们的二维码
(1)在maven中导入类库:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.fengli</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>test</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--就是这个。用来生成二维码 -->
<!-- https://mvnrepository.com/artifact/com.google.zxing/core -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
(2)编写controller类
在开始之前,需要提一下。我用的是springboot框架。我的项目结构图如下(controllers包下面只有QRG是一个controller,其他两个都是工具类):
QRG.java:该类用来生成二维码
package com.fengli.test.controllers;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*该类用于生成二维码*/
@RestController
public class QRG {
@RequestMapping("/generateqrcode")
@ResponseBody
public void generateQRCodeShopAuth(HttpServletRequest request, HttpServletResponse response) {
try {
//获取地址栏的url地址
String longUrl = request.getParameter("url");
// 长的url,可能会生成二维码失败
String shortUrl = ShortURLUtil.getShortURL(longUrl);
// 将字符串转换为bitMatrix
BitMatrix qRcodeImg = QRCodeUtil.generateQRCodeStream(shortUrl, response);
MatrixToImageWriter.writeToStream(qRcodeImg, "png", response.getOutputStream());
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
(2)长url地址转短url地址
这里,我们使用 百度的短地址服务
ShortURLUtil.java:将长的URL地址转换为短的url地址。因为长的url地址可能会生成失败
package com.fengli.test.controllers;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
public class ShortURLUtil {
/*
* 用于缩短URL地址
* @param orginURL 元素url
* */
public static String getShortURL(String originURL) {
String params = "{\"url\":\""+ originURL + "\"}";
//用于装缩短后的url地址
String tinyUrl = null;
try {
//提供短URL服务
URL url = new URL("https://dwz.cn/admin/v2/create");
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
/* 设置connection的一些参数*/
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setConnectTimeout(TIMEOUT);
connection.setRequestMethod("POST");
// token去https://dwz.cn/console/apidoc找
connection.setRequestProperty("Token", "accc9177b277e2f709ad67ae4f36f9de");
connection.setRequestProperty("Content-Type", "application/json"); // 设置发送数据的格式
connection.connect();
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8"); // utf-8编码
out.append(params);
out.flush();
out.close();
//获取返回的短url json
String responseStr = getResponseStr(connection);
System.out.println("response string: " + responseStr);
//短url json中的tinyurl
tinyUrl = getValueByKey_JSON(responseStr, "ShortUrl");
System.out.println("tinyurl: " + tinyUrl);
connection.disconnect();
} catch (IOException e) {
System.out.println("getshortURL error:" + e.toString());
}
return tinyUrl;
}
//地址超时时间
public static int TIMEOUT = 30 * 1000;
public static String ENCODING = "UTF-8";
/**
* JSON get value by key
*
* @param replyText
* @param key
* @return
*/
private static String getValueByKey_JSON(String replyText, String key) {
ObjectMapper mapper = new ObjectMapper();
JsonNode node;
String tinyUrl = null;
try {
node = mapper.readTree(replyText);
tinyUrl = node.get(key).asText();
} catch (JsonProcessingException e) {
// TODO Auto-generated catch block
System.out.println("getValueByKey_JSON error:" + e.toString());
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("getValueByKey_JSON error:" + e.toString());
}
return tinyUrl;
}
/**
* 通过HttpConnection 获取返回的字符串
*
* @param connection
* @return
* @throws IOException
*/
private static String getResponseStr(HttpURLConnection connection)
throws IOException {
StringBuffer result = new StringBuffer();
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream in = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(
in, ENCODING));
String inputLine = "";
while ((inputLine = reader.readLine()) != null) {
result.append(inputLine);
}
}
return String.valueOf(result);
}
}
(3) 生成二维码
现在,短url有了,只差生成二维码了。现在我们就用到了zing第三方类库了。zing关键是使用
bitMatrix = new MultiFormatWriter().encode(url,BarcodeFormat.QR_CODE, 300, 300, hints);
来生成二维码。
QRUtil.java:用于生成二维码
package com.fengli.test.controllers;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
public class QRCodeUtil {
/**
*
* 用于将字符串生成二维码. <br/>
* date: 2018年8月27日 下午12:25:52.<br/>
* @author fengli
* @param url
* @param resp
* @return
*
*/
public static BitMatrix generateQRCodeStream(String url,
HttpServletResponse resp) {
resp.setHeader("Cache-Control", "no-store");
resp.setHeader("Pragma", "no-cache");
resp.setDateHeader("Expires", 0);
resp.setContentType("image/png");
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
hints.put(EncodeHintType.MARGIN, 0);
BitMatrix bitMatrix;
try {
//QR_CODE(Code 39)意思是生成二维码
bitMatrix = new MultiFormatWriter().encode(url,
BarcodeFormat.QR_CODE, 300, 300, hints);
} catch (WriterException e) {
e.printStackTrace();
return null;
}
return bitMatrix;
}
}
现在整个过程完了。让我们看一下运行效果。
当输入(url为要被生成二维码的url地址)
http://localhost:8080/generateqrcode?url=http://www.baidu.com
然后结果:
用手机扫描会跳转到百度首页。
三、总结
//BarcodeFormat.QR_CODE指定你想生成那种条形码
BitMatrix bitMatrix = new MultiFormatWriter().encode(url,
BarcodeFormat.QR_CODE, 300, 300, hints);