【若依 - 前后端不分离版】SysCaptchaController 详解:生成与处理验证码

在现代 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;
    }
}

推荐:若依


在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Peter-Lu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值