Servlet之 验证码(初级)
需求:
使用Servlet向页面响应验证码,并且点击验证码或者"看不清楚,换一张"可以刷新验证码
需求分析:
Servlet中需要完成的需求:
- 验证码的本质:就是一张图片
- 使用Servlet向页面响应验证码和现实中使用画板绘画一样:
1.设置画布的尺寸:宽度(width),高度(height)
2.有了画布之外还需要画笔
3.设置画笔的颜色,使用RGB颜色,red,green,blue三种颜色随机组合
4.要组合颜色就需要使用Random随机生成器对象
5.画布的背景颜色默认为black,我们需要随机更改画布的背景色 - 画布准备就绪以后,就需要准备验证码的素材了
准备一串字符串,包含26个大写字母、26个小写字母、0-9数字字母 - 一般验证码的位数为4位,我们在验证码素材字符串中随机选择4位即可
- 将随机选择的字符写入画布中;写入画布的验证码的颜色也是随机的
- 画干扰线(在画布上使用不同的颜色画上几条干扰线)
- 将完成的画布响应到页面即可
HTML页面中需要完成的需求:
- 简单显示几个标签即可(本需求重点不在HTML页面)
- 使用JavaScript实现点击验证码和点击"看不清楚,换一张"刷新验证码的需求
HTML页面代码实现:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>login</title>
</head>
<body>
<form action="/day28_response/checkcodeServlet" method="post">
<table>
<tr>
<td>用户名</td>
<td><input type="text" name="username"/></td>
</tr>
<tr>
<td>密码</td>
<td><input type="password" name="password"/></td>
</tr>
<tr>
<td>验证码:</td>
<td><input type="password" name="checkcode"/></td>
</tr>
<tr>
<td></td>
<td><img id="img" src="/day28_response/checkcodeServlet"/></td>
<td><a href="javascript:void(0)" id="change">看不清楚,换一张</a></span></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="登录"/></td>
</tr>
</table>
</form>
</body>
</html>
<script>
//给验证码图片和"看不清楚,换一张"绑定单击事件
window.onload = function () {
var img = document.getElementById("img");
img.onclick=function () {
img.src="/day28_response/checkcodeServlet?r="+new Date().getTime();
};
var change = document.getElementById("change");
change.onclick = function () {
img.src="/day28_response/checkcodeServlet?r="+new Date().getTime();
}
}
</script>
Servlet中代码实现:
package servlet;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
@WebServlet("/checkcodeServlet")
public class CheckcodeServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//创建画布
//画布的宽,高
int width = 120;
int height = 40;
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//获得画笔
Graphics graphics = bufferedImage.getGraphics();
//获取随机对象
Random random = new Random();
//设置画笔颜色随机生成
//graphics.setColor(Color.gray);//固定颜色
graphics.setColor(new Color(random.nextInt(255),random.nextInt(255),random.nextInt(255)));
//填充背景颜色
graphics.fillRect(0, 0, width, height);
//生成随机字符
//准备数据
String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
//声明变量存储生成的验证码
String code = "";
//随机生成4个字符
for (int i = 1; i <= 4; i++) {
//设置字体
graphics.setFont(new Font("宋体", Font.HANGING_BASELINE, 30));
//随机生成颜色
graphics.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
//随机生成字符索引
int index = random.nextInt(str.length());
String cha = str.charAt(index) + "";
//将随机生成的字符写入画布,并且验证码写入画布的位置不在一条线上
graphics.drawString(cha, 120 / 5 * i, random.nextInt(height / 2) + height / 2);
code += cha;
}
//画干扰线:
for (int i = 0; i < 10; 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));
}
//将画布写到浏览器中
ImageIO.write(bufferedImage, "png", response.getOutputStream());
}
}
实现效果
- 打开HTML页面显示的效果:
- 刷新HTML页面后,验证码也随之刷新:
- 点击验证码图片,验证码随即刷新:
- 点击"看不清楚,换一张"也可以实现刷新验证码的效果:
- 可多次刷新验证码: