工具类
工具类包含两个核心方法:
getCode(Integer width, Integer height):生成算数验证吗
getCode(Integer width, Integer height, Integer count, Integer size):生成普通验证码
public class Captcha {
/**
* 生成验证码图片
*
* @param width 图片宽度,默认:130
* @param height 图片高度,默认:40
* @param count 验证码字符个数,默认:4
* @param size 验证码干扰麻点的个数,默认:150
* @return Map<String, BufferedImage> 键:生成的验证码;值:图片缓冲对象
* @throws Exception
*/
public static Map<String, BufferedImage> getCode(Integer width, Integer height, Integer count, Integer size) {
// 定义图片的宽高
width = (width == null || width == 0) ? 130 : width;
height = (height == null || height == 0) ? 40 : height;
// 验证码的个数
count = (count == null || count == 0) ? 4 : count;
size = (size == null || size == 0) ? 150 : size;
// 字符库
char[] codes = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'};
// 图片缓冲区,定义宽高和颜色的编码
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 获取画板
Graphics graphics = bi.getGraphics();
// 设置颜色
graphics.setColor(Color.WHITE);
// 填充背景色
graphics.fillRect(0, 0, width, height);
// 从字符库中获取内容
Random random = new Random();
// 存储验证码
StringBuffer sb = new StringBuffer();
// 循环获取随机的字符
for (int i = 1; i <= count; i++) {
// 随机数,生成 0 - 字符库数量
int index = random.nextInt(codes.length);
// 从字符库中获取字符
String code = codes[index] + "";
sb.append(code);
// 设置画笔颜色
graphics.setColor(new Color(getRandomColor(), getRandomColor(), getRandomColor()));
// 设置字体样式
Font font = new Font("微软雅黑", Font.ITALIC, height / 2 + 5);
graphics.setFont(font);
// 把字符画到画布上
graphics.drawString(code, width / (count + 2) * i, height / 2 + 5);
}
// 线条干扰项
// 设置画笔颜色
graphics.setColor(new Color(getRandomColor(), getRandomColor(), getRandomColor()));
// 画线
graphics.drawLine(10, 10, 120, 30);
graphics.drawLine(10, 30, 120, 10);
// 随机麻点干扰项
for (int j = 0; j < size; j++) {
// 设置画笔颜色
graphics.setColor(Color.RED);
int x = random.nextInt(width);
int y = random.nextInt(height);
// 画线
graphics.drawLine(x, y, x, y);
}
Map<String, BufferedImage> map = new HashMap<String, BufferedImage>();
map.put(sb.toString(), bi);
return map;
}
/**
* 生成表达式验证码
* @param width 图片宽度,默认:130
* @param height 图片高度,默认:40
* @return Map<String, BufferedImage> 键:表达式的值;值:图片缓冲对象
*/
public static Map<String, BufferedImage> getCode(Integer width, Integer height) {
// 定义图片的宽高
width = (width == null || width == 0) ? 130 : width;
height = (height == null || height == 0) ? 40 : height;
// 图片缓冲区,定义宽高和颜色的编码
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 获取画板
Graphics graphics = bi.getGraphics();
// 设置颜色
graphics.setColor(Color.WHITE);
// 填充背景色
graphics.fillRect(0, 0, width, height);
// 定义随机数对象
Random random = new Random();
// 获取10以内的随机值
int i1 = random.nextInt(10);
int i2 = random.nextInt(10);
// 定义运算符数组
char[] operators = {'+', '-', '*', '/'};
// 根据数组获取随机下标
int index = random.nextInt(operators.length);
// 根据下标获取运算符
String operator = operators[index] + "";
// 定义结果
int result = 0;
// 判定运算符
switch (operator){
case "+":
result = i1 + i2;
break;
case "-":
result = i1 - i2;
break;
case "*":
result = i1 * i2;
break;
case "/":
result = i1 / i2;
break;
}
// 设置画笔颜色
graphics.setColor(new Color(getRandomColor(), getRandomColor(), getRandomColor()));
// 设置字体样式
Font font = new Font("微软雅黑", Font.ITALIC, height / 2 + 5);
graphics.setFont(font);
// 构建表达式
String expression = i1 + " " + operator + " " + i2 + " = " + " ?";
// 把表达式画到画布上
graphics.drawString(expression, width / 15, height / 2 + 5);
// 存储结果
Map<String, BufferedImage> map = new HashMap<String, BufferedImage>();
map.put(result + "", bi);
return map;
}
/**
* 随机生成颜色代码,范围是0-255的rgb颜色
*
* @return
*/
public static int getRandomColor() {
return new Random().nextInt(255);
}
}
测试类
测试类基于 Servlet 编写,也可以使用 SSM 框架和其他框架。
@WebServlet("/getCode")
public class GetCodeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 通过工具类获取验证码map,图片的宽高可以从前台页面获取
Map<String, BufferedImage> code = Captcha.getCode(130, 40, 4, null);
// 遍历map
Iterator<String> iterator = code.keySet().iterator();
if(iterator.hasNext()){
// 获取key
String key = iterator.next();
// 把key存储到Session中便于登录时获取校验
req.getSession().setAttribute("yzmCode", key);
// 通过key获取字符缓冲对象,写入磁盘
ImageIO.write(code.get(key), "JPEG", new FileOutputStream("D://yzmCode.jpg"));
// 通过key获取字符缓冲对象,写入浏览器输出对象
ImageIO.write(code.get(key), "JPEG", resp.getOutputStream());
}
}
}