redisSerializer = new StringRedisSerializer();Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); MyObjectMapper objectMapper = new MyObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); // 配置序列化
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
RedisCacheConfiguration redisCacheConfiguration = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2 return RedisCacheManager.builder(factory).cacheDefaults(redisCacheConfiguration).build(); }
private class MyObjectMapper extends ObjectMapper { private static final long serialVersionUID = 1L; public MyObjectMapper() { super();
// 去掉各种@JsonSerialize注解的解析
this.configure(MapperFeature.USE_ANNOTATIONS, false); // 只针对⾮空的值进⾏序列化
this.setSerializationInclusion(JsonInclude.Include.NON_NULL); // 将类型序列化到属性json字符串中
this.enableDefaultTyping(DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); // 对于找不到匹配属性的时候忽略报错
this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // 不包含任何属性的bean也不报错
this.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); } }}
好了这下反序列化的问题解决了,redis中
[
\"com.alance.springcachedemo.entity.User\ {
\"name\": \"long\ \"age\": 18, \"height\": 1.72 }]
redis存储的json中带上了类型⾄此这个问题就解决了。
后记
在愉快使⽤缓存注解的时候,发现缓存注解并 不能和诸如事务注解线程池注解⼀起使⽤。这是aop代理的特性决定的。⽽且 ⽅法的类内部调⽤也不⾛注解。enableDefaultTyping 这个功能涉及到java著名的反序列化漏洞。各位系统之间调⽤数据的项⽬还是慎重使⽤.
后记的后记
在写代码的过程中发现了⼀个更优雅的解决⽅案分享给⼤家。
只需要在配置⽂件中配置⼀下CacheManger,使⽤jackson的⼀个带泛型的序列化⼯具实现。
/**
* spring cache 注解相关序列化操作 */
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(); StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); // 配置序列化
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig(); RedisCacheConfiguration redisCacheConfiguration = config // 键序列化⽅式 redis字符串序列化
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(stringRedisSerializer)) // 值序列化⽅式 简单json序列化
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(genericJackson2JsonRedisSerializer)); return RedisCacheManager.builder(factory).cacheDefaults(redisCacheConfiguration).build(); }⼤佬的启发