ssm获取session中验证码值为null问题

本文档记录了一位开发者在前后端分离的环境中遇到的验证码session获取问题。开发者使用了Kaptcha框架,并在web.xml中配置了Servlet,但初次尝试时在session中获取验证码值为null。经过排查,发现是获取session键值对时的键不正确,修正后成功从session中获取到验证码。此外,还总结了几个关键点,包括前端配置、验证码刷新、session创建等。对于跨域时的session问题,作者提出了一些可能的解决方案,但未进行深入验证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

环境:前后端分离,部署在同一台服务器上

问题:前端登录页面实现验证码功能,使用的是catpcha框架,在web.xml中配置,但是在验证码验证中获取不到captcha在session的值,显示为null。

过程:

1、导入maven坐标

<dependency>
    <groupId>com.github.penggle</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3.2</version>
    <exclusions>
        <exclusion>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>

2、web.xml 配置Servlet

<servlet>
    <servlet-name>cap</servlet-name>
    <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
    <init-param>
        <param-name>kaptcha.border</param-name>
        <param-value>no</param-value>
    </init-param>
    <init-param>
        <param-name>kaptcha.textproducer.char.length</param-name>
        <param-value>4</param-value>
    </init-param>
    <init-param>
        <param-name>kaptcha.textproducer.char.string</param-name>
        <param-value>abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789</param-value>
    </init-param>
    <init-param>
        <param-name>kaptcha.background.clear.to</param-name>
        <param-value>211,229,237</param-value>
    </init-param>
    <init-param>
        <!-- session.setAttribute("captcha","验证码") -->
        <param-name>kaptcha.session.key</param-name>
        <param-value>captcha</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>cap</servlet-name>
    <!-- 请求如下地址,就能获取一个验证码图片 -->
    <url-pattern>/captcha</url-pattern>
</servlet-mapping>

3、vue登录页面

4、后端代码

String kaptchaExpected = (String)request.getSession().getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
System.out.println("session中获取的验证码:"+kaptchaExpected);
String kaptchaReceived = request.getParameter("code");
System.out.println("前端提交的验证码:"+kaptchaReceived);

4、登录请求

5、打印输出

解决办法:

 最后发现是获取session的键值对写错了,把

com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY改为setAttribute对应的key,我的是web.xml中帮我创建放到session中了,键值对为captcha。

如果没在web.xml中配置,则要自己手动创建,参考这篇文章:http://t.csdn.cn/iCgqu

成功获取

总结:

1、前后端都没有配置// axios.defaults.withCredentials=true//

allow-credentials="true"

允许跨域时携带cookie,但是仍然可以访问到session中的值,说明是不是使用的同一个session,这个我还没有验证,有大佬可以验证一下。

2、验证码得刷新session中才能获取,如果保持旧的验证码获取session为空。

3、如果没有配置setAttribute放到session中,则getAttribute后面就填我上面过程第4步的代码,自己没有设置键值对,就用谷歌默认的键值对,也能获取到session中的值。

4、写得不好大佬多多指出,我不懂的还有好多好多。


参考文章: 基于ssm实现验证码功能 - 默小希 - 博客园 (cnblogs.com)

 

 

 

 

 

 

实现验证码功能需要以下步骤: 1. 在前端页面添加验证码输入框和图片显示区域。 2. 在后端实现生成验证码图片的功能,并将生成的验证码存储到 session 中。 3. 在前端页面中,使用 Ajax 技术向后台请求生成验证码图片,并将生成的图片显示在页面上。 4. 在用户提交表单时,将用户输入的验证码session 中存储的验证码进行比对,以验证验证码是否正确。 以下是一个基于 Spring + Spring MVC + MyBatis 框架的 ssm 验证码功能的实现示例: 1. 在前端页面中添加验证码输入框和图片显示区域: ```html <div> <label for="captcha">验证码:</label> <input type="text" id="captcha" name="captcha" /> <img id="captchaImg" src="#" alt="验证码" /> <a href="#" onclick="reloadCaptcha();return false;">换一张</a> </div> ``` 2. 在后端实现生成验证码图片的功能,并将生成的验证码存储到 session 中: ```java @Controller public class CaptchaController { // 生成验证码图片 @RequestMapping("/captcha") public void captcha(HttpServletRequest request, HttpServletResponse response) throws Exception { // 生成验证码字符串 String captchaText = generateCaptchaText(); // 将验证码字符串存储到 session 中 request.getSession().setAttribute("captcha", captchaText); // 生成验证码图片 BufferedImage captchaImage = generateCaptchaImage(captchaText); // 输出验证码图片 response.setContentType("image/png"); ImageIO.write(captchaImage, "png", response.getOutputStream()); } // 生成验证码字符串 private String generateCaptchaText() { // 随机生成 4 位数字验证码 Random random = new Random(); int captchaInt = random.nextInt(9000) + 1000; return String.valueOf(captchaInt); } // 生成验证码图片 private BufferedImage generateCaptchaImage(String captchaText) { // 创建 BufferedImage 对象 BufferedImage image = new BufferedImage(100, 40, BufferedImage.TYPE_INT_RGB); // 获取 Graphics2D 对象 Graphics2D g = image.createGraphics(); // 设置背景色 g.setColor(Color.WHITE); g.fillRect(0, 0, 100, 40); // 绘制验证码文本 g.setColor(Color.BLACK); g.setFont(new Font("Arial", Font.BOLD, 20)); g.drawString(captchaText, 20, 25); // 绘制干扰线 for (int i = 0; i < 10; i++) { int x1 = random.nextInt(100); int y1 = random.nextInt(40); int x2 = random.nextInt(100); int y2 = random.nextInt(40); g.drawLine(x1, y1, x2, y2); } // 销毁 Graphics2D 对象 g.dispose(); return image; } } ``` 3. 在前端页面中,使用 Ajax 技术向后台请求生成验证码图片,并将生成的图片显示在页面上: ```javascript function reloadCaptcha() { // 生成随机数,避免浏览器缓存图片 var randomNum = Math.floor(Math.random() * 100000); // 发送 Ajax 请求,获取验证码图片 $.get("/captcha?rand=" + randomNum, function(data) { // 更新验证码图片的 src 属性 $("#captchaImg").attr("src", "data:image/png;base64," + data); }); } ``` 4. 在用户提交表单时,将用户输入的验证码session 中存储的验证码进行比对,以验证验证码是否正确: ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public boolean login(String username, String password, String captcha, HttpSession session) { // 获取 session 中存储的验证码 String captchaInSession = (String) session.getAttribute("captcha"); // 比对验证码是否正确 if (captchaInSession == null || !captchaInSession.equalsIgnoreCase(captcha)) { return false; } // 验证用户名和密码是否正确 User user = userMapper.getUserByUsernameAndPassword(username, password); return user != null; } } ``` 以上就是一个基于 Spring + Spring MVC + MyBatis 框架的 ssm 验证码功能的实现示例。需要注意的是,该示例中的验证码生成算法较为简单,实际开发中应该使用更加复杂的算法来提高验证码的安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值