You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Session集成Redis遇NotSerializableException问题求助

解决Redis存储HttpSession时的SerializationException问题

这个问题我之前帮同事排查过,本质是你的HttpSession里不小心存入了被Spring CGLIB代理的Bean实例,而这个代理类org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor并没有实现Serializable接口,所以Redis序列化Session的时候就抛出了异常。

下面是具体的解决步骤,按优先级从高到低推荐:

1. 排查并修正Session存储的对象(最推荐)

首先检查你代码里所有调用session.setAttribute()的地方,看看是不是把Spring管理的Bean(比如标注了@Service、@Component、@Configuration的类实例)直接存入了Session。这些Bean默认是被CGLIB动态代理的,代理类本身不支持序列化。

解决思路是:不要直接存Bean实例,而是提取需要的业务数据,放到一个**实现了Serializable接口的普通POJO(DTO)**里再存入Session。

举个例子:
错误写法:

@Autowired
private UserService userService;

// 错误:直接存入Spring代理的Bean
session.setAttribute("userService", userService);

正确写法:

// 先定义一个可序列化的DTO类
public class UserSessionDTO implements Serializable {
    private Long userId;
    private String username;
    
    // 无参构造、getter/setter
}

// 提取业务数据存入DTO
UserSessionDTO userSessionInfo = new UserSessionDTO();
userSessionInfo.setUserId(userService.getCurrentUserId());
userSessionInfo.setUsername(userService.getCurrentUsername());

// 存入Session
session.setAttribute("userSessionInfo", userSessionInfo);

2. 若必须存Bean,调整Spring代理方式(不推荐)

如果确实有需求要把Bean存入Session,需要做两个调整:

  • 让你的Bean类实现Serializable接口;
  • 将Spring的代理方式从CGLIB改为JDK动态代理(JDK代理生成的类默认支持序列化,但要求Bean必须实现至少一个接口)。

配置方式:
在你的@Configuration类上添加注解:

@EnableAspectJAutoProxy(proxyTargetClass = false)

或者XML配置:

<aop:aspectj-autoproxy proxy-target-class="false"/>

3. 替换Redis序列化器(备选方案)

如果不想修改Session存储的内容,可以替换Spring Session使用的Redis序列化器,用JSON序列化代替默认的JDK序列化,这样不需要对象实现Serializable接口。

配置示例:

@Configuration
public class RedisSessionConfig {
    @Bean
    public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
        // 使用Jackson JSON序列化器
        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        // 配置Jackson支持序列化所有类型,包括私有字段等
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(objectMapper);
        return serializer;
    }
}

注意:使用JSON序列化时,要确保Session中的对象能被Jackson正确处理(比如有无参构造函数、字段可访问等)。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:23:19