文章目录
- 一、SysCaptchaController 类概述
- 1. 类的功能
- 2. 主要功能
- 二、验证码生成流程
- 1. 接口定义
- 2. 代码流程解析
- 2.1. 设置响应头
- 2.2. 生成验证码
- 2.3. 存储验证码
- 2.4. 返回验证码图片
- 三、处理异常和流关闭
- 1. 异常处理
- 2. 流关闭
- 四、实际应用中的验证码处理
- 1. 验证码生成和展示
- 2. 验证码验证
- 3. 错误调试和日志记录
- 五、完整代码
在现代 Web 应用中,验证码用于增强安全性,防止恶意行为。本文将详细介绍
SysCaptchaController
类,该类负责生成并返回验证码图片。我们将探讨其核心功能、如何处理不同类型的验证码、以及代码中的关键实现细节,帮助开发者更好地理解和应用验证码生成技术。
一、SysCaptchaController 类概述
1. 类的功能
SysCaptchaController
是一个 Spring Boot 控制器类,用于生成并返回验证码图片。该控制器支持两种类型的验证码:
- 算术验证码:例如:
3 + 7 = ?
- 字符验证码:例如:
ABCD
2. 主要功能
- 生成验证码图片:根据请求参数生成不同类型的验证码图片。
- 设置响应头:确保验证码图片不会被缓存。
- 将验证码存储到会话中:用于后续的验证码验证。
二、验证码生成流程
1. 接口定义
@GetMapping(value = "/captchaImage")
public ModelAndView getKaptchaImage(HttpServletRequest request, HttpServletResponse response)
此接口处理验证码生成的请求,并将验证码图片返回给客户端。
2. 代码流程解析
2.1. 设置响应头
response.setDateHeader("Expires", 0);
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
response.addHeader("Cache-Control", "post-check=0, pre-check=0");
response.setHeader("Pragma", "no-cache");
response.setContentType("image/jpeg");
这些设置确保验证码图片不会被缓存,每次请求都会生成新的验证码图片。
2.2. 生成验证码
String type = request.getParameter("type");
BufferedImage bi = null;
String code = null;
if ("math".equals(type)) {
String capText = captchaProducerMath.createText();
code = capText.substring(capText.lastIndexOf("@") + 1);
String capStr = capText.substring(0, capText.lastIndexOf("@"));
bi = captchaProducerMath.createImage(capStr);
} else if ("char".equals(type)) {
code = captchaProducer.createText();
bi = captchaProducer.createImage(code);
}
根据请求参数中的 type
,生成相应类型的验证码。captchaProducerMath
用于生成算术验证码,captchaProducer
用于生成字符验证码。
2.3. 存储验证码
HttpSession session = request.getSession();
session.setAttribute(Constants.KAPTCHA_SESSION_KEY, code);
将生成的验证码存储到用户的会话中,以便在后续的验证码验证中使用。
2.4. 返回验证码图片
try (ServletOutputStream out = response.getOutputStream()) {
ImageIO.write(bi, "jpg", out);
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
将生成的验证码图片通过响应流返回给客户端,并确保流在操作完成后正确关闭。
三、处理异常和流关闭
1. 异常处理
catch (Exception e) {
e.printStackTrace();
}
捕获并打印异常信息,以便于调试和修复问题。
2. 流关闭
finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
确保输出流在使用完毕后被正确关闭,防止资源泄露。
四、实际应用中的验证码处理
1. 验证码生成和展示
确保验证码图片能够正确生成,并在前端展示。客户端通过 GET
请求获取验证码图片,并将其展示给用户。
2. 验证码验证
在用户提交验证码时,将用户输入的验证码与存储在会话中的验证码进行比对。匹配成功则允许继续操作,否则返回错误信息提示用户。
// 示例:验证码验证
String storedCode = (String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
if (!userInputCode.equals(storedCode)) {
throw new VerificationCodeException("验证码错误");
}
3. 错误调试和日志记录
使用适当的日志记录工具来记录验证码生成和验证过程中的错误,以便于后续的调试和修复。
catch (Exception e) {
logger.error("验证码生成或验证过程中发生错误", e);
}
五、完整代码
SysCaptchaController
类提供了一个有效的验证码生成和处理方案,通过生成算术或字符验证码并将其返回给客户端,提高了 Web 应用的安全性。
package com.ruoyi.web.controller.system;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import com.ruoyi.common.core.controller.BaseController;
/**
* 图片验证码(支持算术形式)
*
* @author ruoyi
*/
@Controller
@RequestMapping("/captcha")
public class SysCaptchaController extends BaseController
{
@Resource(name = "captchaProducer")
private Producer captchaProducer;
@Resource(name = "captchaProducerMath")
private Producer captchaProducerMath;
/**
* 验证码生成
*/
@GetMapping(value = "/captchaImage")
public ModelAndView getKaptchaImage(HttpServletRequest request, HttpServletResponse response)
{
ServletOutputStream out = null;
try
{
HttpSession session = request.getSession();
response.setDateHeader("Expires", 0);
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
response.addHeader("Cache-Control", "post-check=0, pre-check=0");
response.setHeader("Pragma", "no-cache");
response.setContentType("image/jpeg");
String type = request.getParameter("type");
String capStr = null;
String code = null;
BufferedImage bi = null;
if ("math".equals(type))
{
String capText = captchaProducerMath.createText();
capStr = capText.substring(0, capText.lastIndexOf("@"));
code = capText.substring(capText.lastIndexOf("@") + 1);
bi = captchaProducerMath.createImage(capStr);
}
else if ("char".equals(type))
{
capStr = code = captchaProducer.createText();
bi = captchaProducer.createImage(capStr);
}
session.setAttribute(Constants.KAPTCHA_SESSION_KEY, code);
out = response.getOutputStream();
ImageIO.write(bi, "jpg", out);
out.flush();
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
try
{
if (out != null)
{
out.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
return null;
}
}
推荐:若依