通过原生Java实现验证码的生成
前言:要看懂本文,你至少得会一些基础JavaScript,JavaWeb,JSP才可以。
1、图片验证码生成的工具类(生成的验证码为字母和数字的随机组合,区分大小写)
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;
/**
* 验证码生成器
*/
public class VerificationCodeGenerator {
//图片宽
private static final int WIDTH = 150;
//图片高
private static final int HEIGHT = 70;
//图片类型
public static final String TYPE = "jpg";
//验证码字符数
private static final byte CODES = 5;
//随机线条数
private static final byte LINES = 20;
//随机背景色
private static final Color[] bgColors = {
Color.DARK_GRAY,Color.pink,Color.LIGHT_GRAY
};
//所有验证码的集合
private static final String verificationCode = "ASDFGHJKLZXCVBNMQWERTYUIOP1234567890zxcvbnmasdfghjklqwertyuiop";
//随机验证码色
private static final Color[] codeColors = {
Color.CYAN,Color.BLUE,Color.GREEN,Color.magenta,Color.YELLOW,Color.WHITE
};
//随机线条的颜色
private static final Color[] lineColors = {
Color.BLUE,Color.WHITE,Color.CYAN,Color.black
};
//验证码字体
private static final Font font = new Font("微软雅黑",Font.BOLD,30);
//随机类
private static final Random random = new Random();
//生成的验证码
private static StringBuffer code = new StringBuffer();
//构造器私有化
private VerificationCodeGenerator(){}
//获取验证码图片
public static BufferedImage getImage(){
//清空验证码
VerificationCodeGenerator.code.delete(0,VerificationCodeGenerator.code.length());
//初始化图片
BufferedImage image = new BufferedImage(WIDTH,HEIGHT, BufferedImage.TYPE_3BYTE_BGR);
//获取画笔
Graphics g = image.getGraphics();
//背景颜色随机索引
int bgIndex = getRandomAmong(bgColors.length);
//将画笔颜色设置为背景索引所指的颜色
g.setColor(bgColors[bgIndex]);
//背景颜色充满图片
g.fillRect(0,0,WIDTH,HEIGHT);
//画边框
g.setColor(Color.black);
g.drawRect(0,0, WIDTH - 1,HEIGHT - 1);
//画随机验证字符
for (int i = 0; i < CODES; i++) {
//设置画笔字体
g.setFont(font);
//随机字符的索引
int codeIndex = getRandomAmong(verificationCode.length());
//获取随机字符
Character randomCode = Character.valueOf(verificationCode.charAt(codeIndex));
//将随机字符追加给静态变量验证码
VerificationCodeGenerator.code.append(randomCode);
//获取验证码的随机颜色
int codeColorIndex = getRandomAmong(codeColors.length);
Color codeColor = codeColors[codeColorIndex];
//将画笔颜色设置为验证码的随机色
g.setColor(codeColor);
//将随机字符画到图片上
g.drawString(randomCode.toString(),WIDTH / 5 * i,HEIGHT >> 1);
}
//画随机线条
for (int i = 1; i < LINES; i++) {
//获取随机线条的颜色
int lineIndex = getRandomAmong(lineColors.length);
//设置画笔颜色为随机线条的颜色
g.setColor(lineColors[lineIndex]);
//设置线条的随机坐标
int x1 = getRandomAmong(WIDTH);
int x2 = getRandomAmong(WIDTH);
int y1 = getRandomAmong(HEIGHT);
int y2 = getRandomAmong(HEIGHT);
//画随机线条
g.drawLine(x1,y1,x2,y2);
}
return image;
}
//获取随机数
private static int getRandomAmong(int max){
return random.nextInt(max);
}
//获取验证码
public static StringBuffer getCode(){
return code;
}
//获取图片类型
public static String getType(){
return VerificationCodeGenerator.TYPE;
}
}
2、在Servlet中的使用
/**
* 将验证码发送到前台
*/
private void checkCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
//调用工具类生成验证码图片
BufferedImage image = VerificationCodeGenerator.getImage();
//将生成的验证码图片写入到响应流中
ImageIO.write(image,"png",response.getOutputStream());
//获取当前图片中的验证码作为校对使用
verificationCode = String.valueOf(VerificationCodeGenerator.getCode());
}
3、前端JSP代码
<%@page pageEncoding="UTF-8" contentType="text/html;charset=utf-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>验证码</title>
<script type="text/javascript">
//页面加载的时候执行此函数
window.onload = function () {
let now = new Date().getTime();
//获取图片
let codeImg = document.getElementById("codeGenerator");
//给验证码图片增加单击事件
codeImg.onclick = function () {
//增加时间戳,达到点击图片就重新向后台发送请求生成新的验证码图片的目的
//如果不增加时间戳,浏览器会认为是同一请求,则不会向后台发送请求,也不会生成新的图片
let now = new Date().getTime();
codeImg.src = "${pageContext.request.contextPath}/checkCode?" + now;
}
//获取按钮
let changeButton = document.getElementById("change_img");
//单击按钮时,重新向后台发送请求
changeButton.onclick = function () {
//alert('单击')
let now = new Date().getTime();
codeImg.src = "${pageContext.request.contextPath}/checkCode?" + now;
}
}
</script>
</head>
<body>
<!--验证码图片-->
<img id = "codeGenerator" style="width: 150px;height: 70px" src="">
<button id="change_img" type="button">看不清,换一张?</button>
</body>
</html>
4、效果图(单击图片或按钮都可更新验证码)
注:按钮可通过CSS样式更改为超链接的样式,我这里就不做了,有兴趣的可以自己完成。