手把手教你用Java实现一个简单的验证码功能

xwbar的头像
2025-12-19 06:35:06
/
世界杯比赛赛程

一、引言

大家好,今天我将带领大家一步步学习如何用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() {

return new ServletRegistrationBean<>(new CaptchaServlet(), "/captcha");

}

}

前端代码如下

id="captchaInput"

type="text"

v-model="userForm.captcha"

placeholder="验证码">

id="captchaImage"

@click="refreshCaptcha"

style="width: 80px;height: 40px"

src="/captcha"

fill="fill">

下面是点击图片刷新验证码的逻辑对应上图中的 @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请求:当浏览器解析到 标签时,它会自动发送一个HTTP GET请求到指定的URL(在本例中是 /captcha) URL映射:在Spring Boot应用中,我定义了一个CaptchaServlet 并将其映射到了 /captcha 路径,这意味着任何到 /captcha 的请求都会被 CaptchaServlet 的 service 方法处理 Servlet处理:当请求到达后端并被映射到 CaptchaServlet 时,CaptchaServlet 的逻辑会被执行,就是刚才咱们写的CaptchaUtils会生成一个验证码图片,并将其作为响应发送回客户端 响应处理:浏览器接收到来自后端的响应,这个响应包含验证码图片的二进制数据,然后,浏览器将这些数据渲染为图片,显示在 标签所在的位置

然后就没有然后了,到此一个简单的验证码功能我们已经实现了 那我们假如要验证该怎么验证呢,在我们上篇文章中loginServlet中有相关逻辑,有兴趣的可以去看一下,在这不再叙述 点击跳转上一篇文章

四、总结

通过本文的讲解,相信大家对Java实现一个简单的验证码功能已经有了一定的了解,还不快去动手试试!

掌握峰值对焦,让你的摄影技术大提升!
亲姐妹用英语怎么说及英文怎么写