har*_*sai 5 java redis spring-data
我正在使用spring-data-redis在spring boot应用程序中缓存数据。我将Mongo用作主要数据源,将Redis用作缓存。当我第一次访问该API时,它会从Mongo中获取记录并将其保存在Cache中,然后将MyObject正确返回给客户端。但是,当我第二次访问该API时,它会在Cache中找到记录,然后尝试将其反序列化回MyObject时,它会变为。总是会遇到强制转换异常:
java.lang.ClassCastException:无法将java.util.LinkedHashMap强制转换为MyObject
这是我的Redis配置:
public class MyConfiguration {
@Bean
public CacheManager cacheManager(RedisTemplate<String, MyObject> redisTemplate) {
return new RedisCacheManager(redisTemplate);
}
@Bean
public RedisTemplate<String, MyObject> redisTemplate(RedisConnectionFactory connectionFactory, ObjectMapper objectMapper) {
StringRedisSerializer serializer = new StringRedisSerializer();
GenericJackson2JsonRedisSerializer hashValueSerializer = new GenericJackson2JsonRedisSerializer(objectMapper);
RedisTemplate<String, MyObject> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(serializer);
redisTemplate.setValueSerializer(hashValueSerializer);
redisTemplate.setConnectionFactory(connectionFactory);
return redisTemplate;
}
}
Run Code Online (Sandbox Code Playgroud)
发现此处报告了相同的问题:Spring-data-redis @Cacheable java.lang.ClassCastException:无法将java.util.HashMap强制转换为java.lang.String
我研究了一段时间,但没有任何想法。请提出建议。在此先感谢一吨。
原因
您已经自定义了objectMapper,并且Redis值中没有类名。所以无法反序列化为真实类型。
您可以检查redis值, redis值中没有“@class”:“com.xxxx.xxx.entity.xx” 。
我的解决方案
@Bean
public RedisCacheConfiguration redisCacheConfiguration(ObjectMapper objectMapper) {
// Do not change the default object mapper, we need to serialize the class name into the value
objectMapper = objectMapper.copy();
// This methodo was deprecated in jackson 2.10 or higher use activateDefaultTyping intead of enableDefaultTyping
// objectMapper = objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
objectMapper = objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
return RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(1))
.disableCachingNullValues()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer(objectMapper)));
}
Run Code Online (Sandbox Code Playgroud)
我objectMapper.enableDefaultTyping()
在深入研究 GenericJackson2JsonRedisSerializer.class 的源代码后使用
小智 5
它对我有用,只需在 Key、value和中设置一个GenericJackson2JsonRedisSerializer()
带有参数的新值,no
serializer
hash key
value serializer
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory, ObjectMapper objectMapper) {
final RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
// value serializer
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
// hash value serializer
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
logger.info("wiring up Redistemplate...");
return redisTemplate;
}
Run Code Online (Sandbox Code Playgroud)
小智 0
它适用于我序列化和反序列化任何对象。在此示例中,缓存管理器设置为 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();
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2193 次 |
最近记录: |