如何正确使用GenericJackson2JsonRedisSerializer来防止丢失类型id属性@class.&l



我已经尝试了好几天来弄清楚如何正确配置GenericJackson2JsonRedisSerializer来处理我的Java pojo。我使用spring-data-redis-2.3.3.RELEASE. 我在不同的配置下获得了许多不同的结果,但没有一个有效。根据我的研究,以下是我认为最正确的配置。

@Bean
public RedisTemplate<String,Object> jsonRedisTemplate() {
ObjectMapper objectMapper = new Jackson2ObjectMapperBuilder().failOnEmptyBeans(false)
.failOnUnknownProperties(false)
.serializationInclusion(JsonInclude.Include.NON_NULL)
.modules(new JavaTimeModule()).build();
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, String.class, MediaList.class, EventScorecard.class, MainScorecard.class, EventStatus.class, EventAttributes.class, ScoreCard.class);
final RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(lettuceConnectionFactory());
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer(objectMapper));
redisTemplate.setHashKeySerializer(new GenericJackson2JsonRedisSerializer(objectMapper));
redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer(objectMapper));
return redisTemplate;
}

将这个RedisTemplate与objectMapper和GenericJackson2JsonRedisSerializer一起使用总是会导致以下错误

无法解析[simple type, class java.lang]的子类型。:缺少类型id属性"@class">

我注意到这个配置的一件事是,如果我将new GenericJackson2JsonRedisSerializer(objectMapper)传递给setKeySerializer,那么错误不会发生,并且返回一个空的[]

我读过大量的其他stackoverflow问题以及网页但我真的没有发现任何显著不同于我,所以我不知道在这一点上。我正在使用Jackson v2.13.3. 如能指点,不胜感激。

编辑

我注意到下面使用Jackson2JsonRedisSerializer而不是GenericJackson2JsonRedisSerializer的配置一切正常。但是,还要注意,我必须直接将特定类型Game.class传递给Jackson2JsonRedisSerializer,以使事情仅为该特定对象工作。我想要的是一个单一的RedisTemplate,可以为我所有的类工作。

@Bean
public RedisTemplate<String,Object> jsonRedisTemplate() {
final RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(lettuceConnectionFactory());
ObjectMapper objectMapper = JsonMapper.builder()
.addModules(new JsonOrgModule()).build();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.configure(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, true);

objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Game.class);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}

DefaultTyping。一切为我经过长时间的研究工作。参考

@Bean
public ReactiveRedisTemplate<String, Object> reactiveRedisTemplate(ReactiveRedisConnectionFactory connectionFactory) {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.EVERYTHING, JsonTypeInfo.As.PROPERTY);
RedisSerializer<Object> redisSerializer = new GenericJackson2JsonRedisSerializer(objectMapper);
RedisSerializationContext<String, Object> context = RedisSerializationContext
.<String, Object>newSerializationContext(RedisSerializer.string())
.value(redisSerializer)
.hashValue(redisSerializer)
.build();
return new ReactiveRedisTemplate<>(connectionFactory, context);
}

相关内容

  • 没有找到相关文章

最新更新