【发布时间】:2019-10-31 09:14:31
【问题描述】:
我在 Spring Boot 2 应用程序中使用 Redis 作为缓存存储。我在某些方法中使用了@Cacheable 注释,并且我想将数据作为非类型化 JSON 存储在 Redis 中。使用我当前的配置,保存数据可以正常工作,但读取它会生成ClassCastException。
所有解决方案、答案、示例和教程都使用 Jackson 的 ObjectMapper 配置 RedisTemplate 或 RedisCacheConfiguration 向 JSON 添加默认类型属性。这里的问题是这个缓存将由不同语言/技术的不同应用程序共享,我不能强制其余应用程序像 Spring Boot 那样工作。
这是我现在拥有的:
配置
@Bean
CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
return RedisCacheManagerBuilder.fromConnectionFactory(connectionFactory)
.cacheDefaults(cacheConfiguration())
.build();
}
private RedisCacheConfiguration cacheConfiguration() {
return RedisCacheConfiguration.defaultCacheConfig()
.disableCachingNullValues()
.serializeKeysWith(SerializationPair.fromSerializer(RedisSerializer.string()))
.serializeValuesWith(SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer(redisMapper())));
}
private ObjectMapper redisMapper() {
return new ObjectMapper()
//.enableDefaultTyping(DefaultTyping.NON_FINAL, As.PROPERTY)
.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
}
服务
@Cacheable(key = "'persons::' + #id")
public Person getPerson(Long id) {
// return person from DB
}
当前配置的结果:
{
"name": "John",
"lastName": "Doe",
"age": 31
}
当 Spring 尝试使用反序列化器从缓存中读取内容时,它找不到带有类型信息的 "@class" 属性,因此它返回 LinkedHashMap。之后,CacheInterceptor 尝试将LinkedHashMap 转换为Person,然后出现ClassCastException。
Request processing failed; nested exception is java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.test.dto.Person
此时,如果我需要为要存储的每种类型编写一个序列化程序,或者我可以为所有人创建一个自定义序列化程序,我可以。到目前为止,我的研究一直没有成功。
感谢您的宝贵时间。
【问题讨论】:
标签: json spring spring-boot caching redis