HTTP——Response实现简易验证码
文章目录
验证码
- 验证码的本质是一张图片
- 验证码的存在可以防止表单的恶意提交
实现步骤
生成验证码图片
创建CheckCode Servlet
- 声明图片的宽高
int width = 100;
int height = 50;
- 创建一个BufferedImage对象
public BufferedImage(int width,int height,int imageType)
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
目前显示效果为
填充图片背景色
- 获取image的画笔对象
Graphics graphics = image.getGraphics();
- 设置画笔颜色为粉色
graphics.setColor(Color.PINK);
- 填充背景色
void fillRect(int x, int y, int width, int height)
参数:起始点坐标,填充宽高
graphics.fillRect(0,0,width,height);
目前显示效果为
绘制图片边框
- 将画笔颜色设置为蓝色
graphics.setColor(Color.BLUE);
- 画出一个矩形作为图片边框
void drawRect(int x, int y, int width, int height)
参数:起始坐标,绘制矩形的宽高
graphics.drawRect(0,0,width-1,height-1);
由于边框自身有1像素的宽度,所以绘制长度需要减1
目前显示效果
显示验证码
- 定义一个字符串来存放验证码可能出现的字符
String s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
- 生成一个随机数作为角标,最大值为s.length
Random random = new Random();
int index = random.nextInt(s.length());
- 循环显示4个字符
void drawString(String str, int x, int y);
参数:输出的字符串,输出坐标
for (int i = 1; i <= 4; i++){
// 生成随机生成索引
int index = random.nextInt(s.length());
char ch = s.charAt(index);
graphics.drawString(ch + "",width / 5 * i,height / 2);
}
目前显示效果
每次刷新即可出现新的验证码
绘制干扰线
- 将画笔颜色设置为绿色
graphics.setColor(Color.green);
- 随机生成干扰线两点坐标
int x1 = random.nextInt(width);
int x2 = random.nextInt(width);
int y1 = random.nextInt(height);
int y2 = random.nextInt(height);
- 循环生成干扰线
void drawLine(int x1, int y1, int x2, int y2)
参数:线的两点坐标
for (int i = 0;i < 8; i++){
// 生成干扰线坐标
int x1 = random.nextInt(width);
int x2 = random.nextInt(width);
int y1 = random.nextInt(height);
int y2 = random.nextInt(height);
graphics.drawLine(x1,y1,x2,y2);
}
目前显示效果
显示图片
boolean write(RenderedImage im,String formatName,OutputStream output)
参数:图片对象,图片后缀名,输出流
ImageIO.write(image,"jpg",response.getOutputStream());
将验证码显示在页面上
- 编写html页面,创建img标签和a标签,img标签src属性连接至checkcode Servlet
<body>
<img id="checkcode" src="/Response/checkcode">
<a id="change" href="javascript:void(0)">更换验证码</a>
</body>
- 编写方法更改src的内容
function changePic() {
img.src = "/Response/checkcode";
}
由于src连接的内容并未发生更改,所以请求会直接从缓存中调用,为了使之发生变化,需要在路径后拼接时间戳
function changePic() {
var date = new Date().getTime();
img.src = "/Response/checkcode?" + date;
}
- 获取元素对象并绑定方法
document.getElementById("change").onclick = changePic;
img.onclick = changePic;
完整代码
CheckCode
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
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("/checkcode")
public class CheckCode extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 定义验证码宽高
int width = 100;
int height = 50;
// 创建BufferedImage对象
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
// 获取画笔对象
Graphics graphics = image.getGraphics();
// 设置画笔颜色为PINK
graphics.setColor(Color.PINK);
// 填充背景
graphics.fillRect(0,0,width,height);
// 设置画笔颜色为BLUE
graphics.setColor(Color.BLUE);
// 绘制边框
graphics.drawRect(0,0,width-1,height-1);
// 定义验证码字符集
String s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
// 循环显示字符
for (int i = 1; i <= 4; i++){
// 生成随机生成索引
int index = random.nextInt(s.length());
char ch = s.charAt(index);
graphics.drawString(ch + "",width / 5 * i,height / 2);
}
// 设置画笔颜色为绿色
graphics.setColor(Color.green);
for (int i = 0;i < 8; i++){
// 生成干扰线坐标
int x1 = random.nextInt(width-1);
int x2 = random.nextInt(width-1);
int y1 = random.nextInt(height-1);
int y2 = random.nextInt(height-1);
graphics.drawLine(x1,y1,x2,y2);
}
// 显示图片
ImageIO.write(image,"jpg",response.getOutputStream());
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CheckCode</title>
<script>
window.onload = function () {
// 点击图片或超链接更换验证码
var img = document.getElementById("checkcode");
function changePic() {
// 添加时间戳
var date = new Date().getTime();
img.src = "/Response/checkcode?" + date;
}
document.getElementById("change").onclick = changePic;
img.onclick = changePic;
}
</script>
</head>
<body>
<img id="checkcode" src="/Response/checkcode">
<a id="change" href="javascript:void(0)">更换验证码</a>
</body>
</html>
使用方法总结
BufferedImage
方法 | 描述 | 参数描述 |
---|---|---|
BufferedImage(int width,int height,int imageType) | BufferedImage构造方法 | 图片宽高,图片类型 |
Graphics
方法 | 描述 | 参数描述 |
---|---|---|
void setColor(Color c) | 设置画笔颜色 | 需要设置的颜色 |
void fillRect(int x, int y, int width, int height) | 填充矩形 | 填充起点坐标,填充矩形宽高 |
void drawRect(int x, int y, int width, int height) | 绘制矩形 | 绘制起点坐标,绘制矩形宽高 |
void drawString(String str, int x, int y) | 绘制字符串 | 字符串,显示坐标 |
void drawLine(int x1, int y1, int x2, int y2) | 绘制线条 | 线条两点坐标 |
ImageIO
方法 | 描述 | 参数描述 |
---|---|---|
boolean write(RenderedImage im,String formatName,OutputStream output) | 输出图片 | 图片对象,图片后缀名,输出流对象 |
Random
方法 | 描述 | 参数描述 |
---|---|---|
int nextInt(int bound) | 生成一个随机的int值 | 生成数的最大值 |