一、引言
大家好,今天我将带领大家一步步学习如何用Java实现验证码功能
验证码在网站和应用程序中起到了非常重要的作用,它可以有效防止恶意注册、登录和垃圾信息等,下面我们就开始吧!
二、验证码概述
简单来说:验证码是一种区分人类与机器人的安全测试,通过要求用户完成特定任务来防止自动化攻击和保障账户安全
三、实现步骤
验证码生成思路
生成随机字符----> 绘制字符到图片----> 添加干扰元素(如线条、噪点等)
那我们直接上代码吧
首先定义了一个CaptchaUtils 用来生成验证码,先定义一会备用
public class CaptchaUtils {
// 验证码字符集
private static final char[] CHAR_SET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".toCharArray();
// 图像宽度和高度
private static final int WIDTH = 80;
private static final int HEIGHT = 40;
// 验证码字符个数
private static final int LENGTH = 4;
/**
* 创建验证码图像并返回验证码上的文本
*
* @param request HttpServletRequest, 用于获取会话
* @param response HttpServletResponse, 用于输出图像到客户端
* @return 返回生成的验证码文本
*/
public static String createCaptchaImage(HttpServletRequest request, HttpServletResponse response) {
// 在这里创建或获取会话
HttpSession session = request.getSession();
// 创建BufferedImage对象,作为图像缓冲区
BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
// 获取Graphics2D对象,用于绘制图像
Graphics2D g = image.createGraphics();
// 设置背景色
g.setColor(Color.WHITE);
g.fillRect(0, 0, WIDTH, HEIGHT);
// 设置字体
g.setFont(new Font("Arial", Font.BOLD, 20));
// 生成随机验证码
StringBuilder captcha = new StringBuilder();
Random random = new Random();
for (int i = 0; i < LENGTH; i++) {
char randomChar = CHAR_SET[random.nextInt(CHAR_SET.length)];
captcha.append(randomChar);
// 设置字体颜色
g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
g.drawString(String.valueOf(randomChar), 20 * i + 10, 30);
}
// 绘制干扰线
for (int i = 0; i < 10; i++) {
g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
g.drawLine(random.nextInt(WIDTH), random.nextInt(HEIGHT), random.nextInt(WIDTH), random.nextInt(HEIGHT));
}
// 释放Graphics2D对象
g.dispose();
// 设置响应头
response.setContentType("image/jpeg");
try {
// 将图像输出到客户端
ImageIO.write(image, "JPEG", response.getOutputStream());
// 刷新输出流
response.getOutputStream().flush();
} catch (IOException e) {
e.printStackTrace();
}
// 将验证码文本保存到会话中,以便进行验证
session.setAttribute("captchaText", captcha.toString());
// 返回生成的验证码文本
return captcha.toString();
}
}
然后我们来定义CaptchaServlet 来处理请求,当CaptchaServlet被调用时候会执行 CaptchaUtils中的创建二维码的逻辑,进而将验证码信息保存到Session中以便后续验证
public class CaptchaServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 创建验证码图片并返回图片上的文本
String captchaText = CaptchaUtils.createCaptchaImage(request,response);
// 将验证码文本保存到Session中
HttpSession session = request.getSession();
session.setAttribute("captcha", captchaText);
}
}
我是在WebConfig中注册的,你可以用别的方式,用户访问/captcha路径时,CaptchaServlet将被调用
@Configuration
public class WebConfig {
@Bean
public ServletRegistrationBean<CaptchaServlet> CaptchaServlet() {
return new ServletRegistrationBean<>(new CaptchaServlet(), "/captcha");
}
}
前端代码如下
<el-form-item label="验证码" prop="captcha" width="120">
<el-row>
<el-col :span="18">
<el-input
id="captchaInput"
type="text"
v-model="userForm.captcha"
placeholder="验证码">
</el-input>
</el-col>
<el-col :span="6">
<el-image
id="captchaImage"
@click="refreshCaptcha"
style="width: 80px;height: 40px"
src="/captcha"
fill="fill">
</el-image>
</el-col>
</el-row>
</el-form-item>
下面是点击图片刷新验证码的逻辑对应上图中的 @click=“refreshCaptcha”
在url后加上new Date().getTime() 的目的是为了确保每次请求验证码时,浏览器不会使用缓存的图片,而是重新从服务器获取一个新的验证码图片
refreshCaptcha() {
$.ajax({
url: '/captcha',
type: 'GET',
contentType: 'application/x-www-form-urlencoded',
processData: false,
success: function (data) {
var captchaImage = document.getElementById('captchaImage');
captchaImage.src = '/captcha?' + new Date().getTime()
}
})
},
那我应该怎么接收这个图像呢?
这是个好问题,我当时因为这个琢磨了好一会子,在开发者工具中能预览图像就是不知道怎么接收,大概如下,可以看的到生成的验证码图形
然后开开心心的点开响应,what???
然后发现,直接在img中的src中写上路径就可以了,可能也有别的方法,希望有大佬可以指点指点
那我就好奇这是为什么呢?
原因如下
HTTP请求
:当浏览器解析到<el-image src="/captcha">
标签时,它会自动发送一个HTTP GET请求到指定的URL(在本例中是 /captcha)
URL映射
:在Spring Boot应用中,我定义了一个CaptchaServlet 并将其映射到了 /captcha 路径,这意味着任何到 /captcha 的请求都会被 CaptchaServlet 的 service 方法处理
Servlet处理
:当请求到达后端并被映射到 CaptchaServlet 时,CaptchaServlet 的逻辑会被执行,就是刚才咱们写的CaptchaUtils会生成一个验证码图片,并将其作为响应发送回客户端
响应处理
:浏览器接收到来自后端的响应,这个响应包含验证码图片的二进制数据,然后,浏览器将这些数据渲染为图片,显示在<el-image>
标签所在的位置
然后就没有然后了,到此一个简单的验证码功能我们已经实现了
那我们假如要验证该怎么验证呢,在我们上篇文章中loginServlet中有相关逻辑,有兴趣的可以去看一下,在这不再叙述
点击跳转上一篇文章
四、总结
通过本文的讲解,相信大家对Java实现一个简单的验证码功能已经有了一定的了解,还不快去动手试试!