You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Spring Boot集成Redis存储Session失败,求问题排查方案

Spring Boot Session 无法存储到 Redis 的问题排查与修复

我来帮你梳理下问题根源,看起来你在Session的使用逻辑和Spring Session的工作机制上出现了混淆,这才导致Session没被正确存入Redis。

核心问题分析

  • 混淆了Session ID和Session属性的概念
    你自己生成了sessionUuid并把它作为Session的属性key(request.getSession().setAttribute(sessionUuid, user)),但Spring Session管理Redis中的Session时,是以HttpSession本身的ID作为Redis的key,而非你自定义的属性key。你用自己生成的UUID去Redis查询,自然找不到对应的Session。

  • 登录状态判断逻辑错误
    你的判断条件request.getSession().getAttribute(session) != null完全不符合预期:这里的session是前端传的参数,但你应该是要通过Session ID验证用户是否已登录,而非查找Session里是否存在某个名为session的属性。而且request.getSession()默认会创建新Session(如果不存在的话),这会导致你每次请求都拿到新Session,根本没法复用。

  • 配置类的冗余问题
    继承AbstractHttpSessionApplicationInitializer是在非Spring Boot环境(比如传统Spring MVC)下用来注册Session过滤器的,Spring Boot环境下不需要这个,@EnableRedisHttpSession已经足够完成自动配置。

修复步骤与代码示例

1. 简化Session配置类

去掉冗余的继承,保留核心配置即可:

@Configuration
@EnableRedisHttpSession
public class SessionConfig {
    @Bean
    public LettuceConnectionFactory connectionFactory() {
        return new LettuceConnectionFactory();
    }
}

2. 重构登录状态判断与Session处理逻辑

正确的逻辑应该是:

  • 如果前端传来有效的Session ID(Spring Session通常会自动从Cookie的JSESSIONID获取,也可让前端在请求头/参数中传递),Spring会自动从Redis加载对应Session。
  • 如果Session不存在(用户未登录),则执行登录逻辑,将用户信息存入当前Session属性,Spring Session会自动把这个Session同步到Redis。

修正后的代码:

UserAttributes findUserByEmailIdOrPhoneNumber(HttpServletRequest request, 
                                             @RequestParam(value = "userLoginWay", required = false) String userLoginWay, 
                                             @RequestParam(value = "userPassword", required = false) String userPassword) {
    // 尝试从当前Session中获取已登录用户,getSession(false)不会创建新Session
    HttpSession existingSession = request.getSession(false);
    UserAttributes loggedInUser = null;
    if (existingSession != null) {
        loggedInUser = (UserAttributes) existingSession.getAttribute("LOGGED_IN_USER");
    }
    
    if (loggedInUser != null) {
        // 用户已登录,直接返回
        return loggedInUser;
    } else {
        // 执行登录逻辑,验证账号密码
        UserAttributes user = login(userLoginWay, userPassword);
        
        // 创建新Session并存入用户信息,Spring会自动同步到Redis
        HttpSession newSession = request.getSession(true);
        newSession.setAttribute("LOGGED_IN_USER", user);
        
        // 可将newSession.getId()返回给前端,方便后续请求携带(如果不用Cookie的话)
        return user;
    }
}

3. 验证Redis中的Session

现在你可以用Session ID去Redis查询,Session ID可通过request.getSession().getId()获取。Redis中存储Session的key格式通常是spring:session:sessions:{sessionId},你可以用keys spring:session:*命令查看所有Session相关key,再用get spring:session:sessions:{你的SessionID}查看具体内容。

额外注意事项

  • 确保你的UserAttributes类实现了Serializable接口,因为存入Redis的对象必须可序列化,否则Spring Session无法将其存入Redis。
  • 检查application.properties的配置已正确生效,Spring Boot会自动读取这些配置连接Redis。

内容的提问来源于stack exchange,提问作者Lokesh Pandey

火山引擎 最新活动