SpringBoot从Jackson2升级到Jackson3缺失@class类型ID属性报错
解决方案:SpringBoot 4.0.2 + Jackson3 Redis序列化配置修复
问题根源
你的Jackson3配置与原Jackson2配置存在三处关键差异,直接导致反序列化时丢失@class类型ID字段:
- 多态类型匹配策略从
EVERYTHING改为NON_CONCRETE_AND_ARRAYS,部分类型序列化时不会生成@class标记 - 替换了Redis序列化器,
JacksonJsonRedisSerializer对Object类型的多态支持远不如原GenericJackson2JsonRedisSerializer友好 - 缺失
JavaTimeModule注册,虽不是当前错误直接原因,但会引发日期时间类型序列化异常
修改后的完整配置代码
import tools.jackson.databind.DeserializationFeature; import tools.jackson.databind.ObjectMapper; import tools.jackson.databind.json.JsonMapper; import tools.jackson.databind.jsontype.DefaultTypeResolverBuilder; import tools.jackson.databind.jsontype.DefaultTyping; import tools.jackson.datatype.jsr310.JavaTimeModule; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializer; @Bean public RedisSerializer<Object> jackson2JsonRedisSerializer() { ObjectMapper objectMapper = getObjectMapper(); // 换回与Jackson2行为一致的GenericJackson2JsonRedisSerializer,适配Object类型多态序列化 return new GenericJackson2JsonRedisSerializer(objectMapper); } private ObjectMapper getObjectMapper() { ObjectMapper objectMapper = JsonMapper.builder().build(); // 注册JavaTimeModule,恢复JDK8日期时间类型序列化支持 objectMapper.registerModule(new JavaTimeModule()); // 对齐Jackson2的多态类型处理逻辑 DefaultTypeResolverBuilder typeResolverBuilder = DefaultTypeResolverBuilder.construct( DefaultTyping.EVERYTHING, // 与原Jackson2的EVERYTHING策略完全一致 objectMapper.getPolymorphicTypeValidator() ); // 指定类型ID为类全限定名,以PROPERTY形式嵌入JSON(即生成@class字段) typeResolverBuilder.init(tools.jackson.databind.jsontype.JsonTypeInfo.Id.CLASS, null); typeResolverBuilder.inclusion(tools.jackson.databind.jsontype.JsonTypeInfo.As.PROPERTY); objectMapper.setDefaultTyping(typeResolverBuilder); // 忽略未知属性,保持原配置行为 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); return objectMapper; }
关键配置说明
- 换回GenericJackson2JsonRedisSerializer:该序列化器专为任意
Object类型设计,自动处理多态类型的@class标记生成与解析,完美适配你的场景 - 对齐多态类型策略:使用
DefaultTyping.EVERYTHING确保所有类型序列化时都生成@class字段,与Jackson2的行为完全匹配 - 显式配置类型解析器:通过
DefaultTypeResolverBuilder指定类型ID为类全限定名,以属性形式嵌入JSON,彻底解决反序列化时找不到类型ID的问题 - 恢复JavaTimeModule注册:避免日期时间类型序列化出现额外异常
内容的提问来源于stack exchange,提问作者Aldo Inácio da Silva




