前言
前段时间因为一些原因要做一个二维码,故此google了许多,当然是在踩了许多坑之后,找到了适合自己的方法,故在此将其总结一下,来提高自己
什么是二维码
总的来说就是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的;在代码编制上巧妙地利用构成计算机内部逻辑基础的“0”、“1”比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,最后通过相关设备读取。
zxing
zxing是google的一个开源源码,主要用于java生成和解析的条形码,二维码,通过引用相关jar包,实现其中的相关接口来开发,这里我引用的是QRCode.jar主要是生成二维码
需求案例
假设我们通过扫描二维码将数据库中的信息取出来并显示在另一个页面
环境准备
MyEclipse、mysql数据库(这里建了一张简单表,有id、name、password)、ssh整合包(事实上,我们可以单独使用struts2,只不过耗时一些),QRCode.jar包,jquery-1.8.3.js,gson.jar
二维码工具包
这里主要有三个类,一个是图像本身类(包含其本身一些属性)、二维码处理类(包括生成和解析图像二维码),最后一个是将本地图片通过调用处理类转化为二维码。
这里我将其放在com.zwl.util包下(以下是相关代码)
|
|
生成和解析二维码类
public class QRCode {
/**
* 解析二维码(QRCode)
* @param imgPath
* @return content(返回二维码内容)
*/
public static String decoderQRCode(String imgPath) {
// QRCode 二维码图片的文件
File imageFile = new File(imgPath);
BufferedImage bufImg = null;
String content = null;
try {
bufImg = ImageIO.read(imageFile);
QRCodeDecoder decoder = new QRCodeDecoder();
content = new String(decoder.decode(new QRCodeImageBean(bufImg)), "utf-8");
} catch (IOException e) {
System.out.println("Error: " + e.getMessage());
e.printStackTrace();
} catch (DecodingFailedException dfe) {
System.out.println("Error: " + dfe.getMessage());
dfe.printStackTrace();
}
return content;
}
/**
* 生成二维码(QRCode)图片
* @param content 存储内容
* @param imgPath 图片路径
* @param imgType 图片类型
*/
public static void encoderQRCode(String content, String imgPath, String imgType) {
encoderQRCode(content, imgPath, imgType, 7);
}
/**
* 生成二维码(QRCode)图片
* @param content 存储内容
* @param imgPath 图片路径
* @param imgType 图片类型
* @param size 二维码尺寸
*/
public static void encoderQRCode(String content, String imgPath, String imgType, int size) {
try {
BufferedImage bufImg = qRCodeCommon(content, imgType, size);
File imgFile = new File(imgPath);
// 生成二维码QRCode图片
ImageIO.write(bufImg, imgType, imgFile);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 生成二维码(QRCode)图片的公共方法
* @param content 存储内容
* @param imgType 图片类型
* @param size 二维码尺寸
* @return
*/
private static BufferedImage qRCodeCommon(String content, String imgType, int size) {
BufferedImage bufImg = null;
try {
Qrcode qrcodeHandler = new Qrcode();
// 设置二维码排错率,可选L(7%)、M(15%)、Q(25%)、H(30%),排错率越高可存储的信息越少,但对二维码清晰度的要求越小
qrcodeHandler.setQrcodeErrorCorrect('M');
qrcodeHandler.setQrcodeEncodeMode('B');
// 设置设置二维码尺寸,取值范围1-40,值越大尺寸越大,可存储的信息越大
qrcodeHandler.setQrcodeVersion(size);
// 获得内容的字节数组,设置编码格式
byte[] contentBytes = content.getBytes("utf-8");
// 图片尺寸
int imgSize = 67 + 12 * (size - 1);
bufImg = new BufferedImage(imgSize, imgSize, BufferedImage.TYPE_INT_RGB);
Graphics2D gs = bufImg.createGraphics();
// 设置背景颜色
gs.setBackground(Color.WHITE);
gs.clearRect(0, 0, imgSize, imgSize);
// 设定图像颜色> BLACK
gs.setColor(Color.BLACK);
// 设置偏移量,不设置可能导致解析出错
int pixoff = 2;
// 输出内容> 二维码
if (contentBytes.length > 0 && contentBytes.length < 800) {
boolean[][] codeOut = qrcodeHandler.calQrcode(contentBytes);
for (int i = 0; i < codeOut.length; i++) {
for (int j = 0; j < codeOut.length; j++) {
if (codeOut[j][i]) {
gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3, 3);
}
}
}
} else {
throw new Exception("QRCode content bytes length = " + contentBytes.length + " not in [0, 800].");
}
gs.dispose();
bufImg.flush();
} catch (Exception e) {
e.printStackTrace();
}
return bufImg;
} }
最后一个类是本地生成二维码图片
|
|
其中imgPath是本地你想将某个图片生成二维码的那个图片
qrCon为解析后的二维码内容,我这里就是一个url地址
encoderContent:设置二维码的内容,这里为url带个参数,扫描后就会跳转到相应界面
这里的参数想要取出,可以先将内容取出,在通过string类中的方法将字符创相应位置字符取出即可
至此,工具类算是有了,接下来就是结合具体配置
后台方法
首先是web.xml(启用struts2和spring)
|
|
然后是applicationContext.xml(为了方便直接将所有方法都注入了)
pojo类(与数据库映射那个类)
|
|
映射文件
|
|
接口
接下来就是接口编写
dao层
service层
|
|
分别得实现类
|
|
这里只有两个页面,一个只有二维码,另一个是扫描后跳转的页面并且可以从数据库中取出相关信息
|
|
Action类
接下来就是action的编写
首先是 QRCodeAction
|
|
然后是我们需要的userreturnaction(主要后台信息通过json格式传给前台)
|
|
注意在页面中需要jquery-1.8.3.js包,同时此处json格式转换用的是gson.jar包
最后就是struts.xml配置
|
|
最后打开含有二维码那个页面,然后扫一扫就可以跳转到含数据的界面,当然笔者之前遇到了几个问题,首先是图片地址在action中要正确,不然出现null,其次这是只能一个二维码并且含参数id的,只能有一个action,当然可以优化。。。