图片验证码
场景描述
在实现登陆或者注册等业务逻辑时,一般都会加上图片验证码进行防止机器人的校验。
解决思路
使用j2se的BufferedImage类来创建用来缓存图片的内存空间,然后调用createGraphics来获得Graphics2D实例,调用该实例的一系列绘图方法来产生图片内容,然后将BufferedImage实例的图片数据,转换为base64编码的字符串,然后前台页面通过如下内容来显示图片。
<img id="verifyIMG" alt="点击更换验证码" src="data:image/png;base64, {%VERIFY_IMG%}">
解决方法
- 创建ImageVerify工具类。
package com.ipu.server.util;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.Random;
public class ImageVerify {
private static Random random = new Random();
public static BufferedImage getImageVerify(String randomCode) {
int width = 100;
int height = 45; // 验证图片的宽度,高度
Color back = getBack();
Color front = getFront(back);
String code = randomCode;
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
Graphics2D g = bi.createGraphics(); // 得到画布
g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 20)); // 设置字体
g.setColor(back);
g.fillRect(0, 0, width, height); // 画背景
g.setColor(front);
g.drawString(code, 18, 20); // 画字符
for (int i = 0, n = random.nextInt(20); i < n; i++) {
g.fillRect(random.nextInt(width), random.nextInt(height), 1, 1);
} // 产生至多20个噪点
return bi;
}
// 得到图片背景色
protected static Color getBack() {
return new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
}
// 生成颜色的反色
protected static Color getFront(Color c) {
return new Color(255 - c.getRed(), 255 - c.getGreen(), 255 - c.getBlue());
}
}
- 创建ImageVerifyCode类。
package com.ipu.server.bean;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.apache.commons.codec.binary.Base64;
import com.ailk.common.data.IData;
import com.ailk.common.data.impl.DataMap;
import com.ipu.server.core.bean.IpuAppBean;
import com.ipu.server.util.ImageVerify;
public class ImageVerifyCode extends IpuAppBean {
public IData generateVerifyCodeImage(IData prama) throws Exception {
IData resultData = new DataMap();
String randomCodeStr = getVerifyCode(6, 2);
System.out.println("=======ImageVerifyCode.generateVerifyCodeImage() randomCode:"+ randomCodeStr);
BufferedImage bImg = ImageVerify.getImageVerify(randomCodeStr);
String encodeImgStr = getFileBase64Str(bImg);
resultData.put("VERIFY_IMG", encodeImgStr);
return resultData;
}
/**
* 将图片文件转化为字节数组字符串,并对其进行Base64编码处理
*
* @param filePath
* 如果文件过大将其转为串的时候会报OutOfMemery错误?
*/
public static String getFileBase64Str(BufferedImage image) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", baos);
byte[] jpegData = baos.toByteArray();
return new String(Base64.encodeBase64(jpegData), "utf-8");
}
/**
* 作用:获取六位随机码
*/
public String getVerifyCode(int length, int verifyCodeType) throws Exception {
String num = "0123456789";
String ch = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ";
String vc = "";
if (verifyCodeType == 0) vc = num;
else if (verifyCodeType == 1) vc = ch;
else vc = num + ch;
char[] chs = vc.toCharArray();
String code = "";
for (int i = 0; i < length; i++) {
code += chs[(int) (Math.random() * vc.length())];
}
return code;
}
}
- 创建VerifyCodeImage.html。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<!--1,引入CSS文件 -->
{%>template/common/Head.html%}
<script type="text/javascript" src="biz/js/VerifyCodeImage.js"></script>
<title>验证码图片demo</title>
</head>
<body>
<div>
<img id="verifyIMG" alt="点击更换验证码" src="data:image/png;base64, {%VERIFY_IMG%}">
</div>
</body>
</html>
- 创建VerifyCodeImage.js。
require(["mobile","zepto","common"],function(Mobile,$,Common){
$("#verifyIMG").click(function(){
Common.callSvc("VerifyCodeImage.generateImage", null, function(data){
var resultData = new Wade.DataMap(data);
$("#verifyIMG").attr("src", "data:image/png;base64, " + resultData.get("VERIFY_IMG"));
});
});
});
- 打开etc/server-data.xml配置文件,添加如下内容:
<action name="VerifyCodeImage.generateImage" class="com.ipu.server.bean.ImageVerifyCode" method="generateVerifyCodeImage" verify="false" ></action>
- 打开etc/server-pages.xml配置文件,添加如下内容:
<action name="VerifyCodeImage.generateImage" class="com.ipu.server.bean.ImageVerifyCode" method="generateVerifyCodeImage" verify="false" ></action>