大致过程:
生成验证码:java生成一张含有随机数字和字母的图片,然后img标签地址引用。
替换验证码:img标签重新提交一次请求。
代码实现:
制作图片的流程就如画画,首先要有一个画板,然后有画纸,接着为画纸打底色,最后作画。
// 用于生成图片的servlet 配置地址为/servlet/yzm
// 实现下列方法就可以了,类结构我就不写了
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设置请求编码,这里不需要获取请求信息可以不用设置
req.setCharacterEncoding("utf-8");
// 设置响应文件类型与编码格式,这里不需要换回文本,编码不是最重要的,文件类型才是最重要的"image/jpeg"
resp.setContentType("image/jpeg;charsert=utf-8");
int width = 88;
int height = 38;
// 创建验证码图片(获得画板)
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 创建画板图层(获得画纸)
Graphics graphics = image.getGraphics();
// 设置画笔颜色
graphics.setColor(Color.white);
// 填充画板图层(为画纸打底色)
graphics.fillRect(0, 0, width - 1, height - 1);
// 可获得的验证数据
String dataString = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
// 设置字体
graphics.setFont(new Font("楷体", Font.BOLD, 30));// 加粗大小30
// 用于储存产生的4个随机字符
StringBuilder builder = new StringBuilder();
Random random = new Random();
int len = dataString.length();
// 获取4个随机单词
for (int i = 0; i < 4; i++) {
// 设置画笔随机颜色
graphics.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
// 随机获取截取字符串的起始位置
int begin = random.nextInt(len);
String data = dataString.substring(begin, begin + 1); // 截取一个字符
// 将随机字符通过定位画入画板
graphics.drawString(data, i * 20, 25);
// 保存字符用于比较用户的输入
builder.append(data);
}
// 画8条干扰线
for (int i = 0; i < 8; i++) {
// 设置画笔随机颜色
graphics.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
// 将干扰线随机定位画入画板
graphics.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width), random.nextInt(height));
}
// 将产生的随机验证码数据保存到对话域中
req.getSession().setAttribute("yzm", builder.toString());
// 将图片通过流传输给客户端
ImageIO.write(image, "png", resp.getOutputStream());
}
处理用户注册或登陆逻辑的servlet
// 配置地址为/servlet/register
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设置请求与响应编码
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
// 这里只演示验证码,其他数据就不列出了
String yzm = req.getParameter("yzm"); // 获取前端发送来的验证码
String yzmData = (String) req.getSession().getAttribute("yzm"); // 获取会话域中的验证码
// 不区分大小写比较
if (yzmData.equalsIgnoreCase(yzm)) { // 核对验证码
// 验证码正确的业务逻辑
} else {
// 验证码不正确的业务逻辑
}
}
html中的代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="servlet/register" method="post">
<input type="text" name="yzm">
<img class="yzm-img" src="servlet/yzm?"><span style="cursor: pointer" onclick="replaceCaptcha()">换一张</span>
<input type="submit" value="Submit">
</form>
<script>
function replaceCaptcha() {
// 要改变图片的请求地址,因为浏览器缓存了图片,地址没有改变的情况下则不会重新获取资源
var imgEle = document.getElementsByClassName("yzm-img")[0];
var src = imgEle.src; // 获取图片请求地址
var begin = src.lastIndexOf("?");
var old = src.substr(begin, src.length - begin);
src = src.replace(old,"?" + Math.random()); // 将地址?及后面的类容替换为随机数
imgEle.src = src;
}
</script>
</body>
</html>