如何正确配置GenericJackson2JsonRedisSerializer解决@class缺失报错
GenericJackson2JsonRedisSerializer 多POJO适配配置方案
Could not resolve subtype of [simple type, class java.lang.Object]: missing type id property '@class'报错由4处配置错误导致,逐一修正即可:
- 错误1:Hash键序列化器选型错误。Redis的key、hashKey都是纯字符串语义,必须使用
StringRedisSerializer,用JSON序列化器处理字符串键会额外包裹转义字符、类型标记,直接导致读值返回空数组、类型解析失败。 - 错误2:自定义ObjectMapper的默认类型配置不完整,且未配置属性可见性规则,序列化Java对象时不会写入
@class类型标识字段,反序列化时自然无法匹配目标类型。 - 错误3:RedisTemplate配置完成后未调用
afterPropertiesSet()执行初始化,自定义的序列化规则不会真正生效。 - 错误4:无需手动将String、基础类型类注册为子类型,这些类型会被默认类型规则自动处理,手动注册反而会覆盖内置的类型解析逻辑。
正确可运行配置
以下配置适配spring-data-redis-2.3.3.RELEASE + Jackson 2.13.3版本,支持所有自定义POJO、基础类型、集合类型的自动序列化/反序列化,无需指定固定类型:
@Bean public RedisTemplate<String, Object> jsonRedisTemplate(RedisConnectionFactory lettuceConnectionFactory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(lettuceConnectionFactory); // 构建ObjectMapper ObjectMapper objectMapper = new Jackson2ObjectMapperBuilder() .failOnEmptyBeans(false) .failOnUnknownProperties(false) .serializationInclusion(JsonInclude.Include.NON_NULL) .modules(new JavaTimeModule()) .build(); // 配置属性可见性,保证所有字段可被序列化 objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); // 配置默认类型规则,非final类序列化时自动写入@class字段 objectMapper.activateDefaultTyping( objectMapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY ); // 日期格式统一 objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); // 仅需要注册自定义多态子类即可,基础类型无需注册 objectMapper.registerSubtypes(Game.class, MediaList.class, EventScorecard.class, MainScorecard.class, EventStatus.class, EventAttributes.class, ScoreCard.class); // 序列化规则配置:key、hashKey统一用字符串序列化,值用GenericJackson2JsonRedisSerializer StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer(objectMapper); redisTemplate.setKeySerializer(stringRedisSerializer); redisTemplate.setValueSerializer(jsonRedisSerializer); redisTemplate.setHashKeySerializer(stringRedisSerializer); redisTemplate.setHashValueSerializer(jsonRedisSerializer); // 必须执行初始化,否则配置不生效 redisTemplate.afterPropertiesSet(); return redisTemplate; }
验证说明
配置生效后,所有存入Redis的非字符串值都会自动在JSON根节点追加@class字段,值为对应类的全限定名,反序列化时会自动根据该字段转成对应Java对象,无需在读取时指定具体类型,满足单RedisTemplate适配所有自定义POJO的需求。
之前测试可用的Jackson2JsonRedisSerializer属于定类型序列化器,构造时传入固定类型后,所有值都会按该类型解析,本身就不支持多类型动态转换,不符合当前需求场景。
内容的提问来源于stack exchange,提问作者After_Sunset
相关产品推荐
相关产品推荐

