gpt4 book ai didi

json - 如何使用 Spring Boot 2 CacheManager 在 Redis 中存储非类型化 JSON

转载 作者:行者123 更新时间:2023-12-02 06:59:56 25 4
gpt4 key购买 nike

我在 Spring Boot 2 应用程序中使用 Redis 作为缓存存储。我在某些方法中使用 @Cacheable 注释,并且希望将数据作为非类型化 JSON 存储在 Redis 中。根据我当前的配置,保存数据工作正常,但读取数据会生成 ClassCastException

所有解决方案、答案、示例和教程都使用 Jackson 的 ObjectMapper 来配置 RedisTemplateRedisCacheConfiguration 向 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,但它对我来说可以序列化和反序列化。在此示例中,缓存管理器设置为 TTL,如果需要,您可以将其删除。

@Configuration
@EnableCaching
public class RedisCacheConfig {

@Value("${spring.redis.host}")
private String redisHostName;

@Value("${spring.redis.port}")
private int redisPort;

@Bean
public LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(new RedisStandaloneConfiguration(redisHostName, redisPort));
}

@Bean
public RedisTemplate<Object, Object> redisTemplate() {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<Object, Object>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
return redisTemplate;
}

@Bean
@Primary
public RedisCacheManager redisCacheManager(LettuceConnectionFactory lettuceConnectionFactory) {
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig().disableCachingNullValues()
.entryTtl(Duration.ofMinutes(1))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json()));

redisCacheConfiguration.usePrefix();

return RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(lettuceConnectionFactory)
.cacheDefaults(redisCacheConfiguration).build();

}
}

关于json - 如何使用 Spring Boot 2 CacheManager 在 Redis 中存储非类型化 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56637032/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com