先放配置
配置显示class和不显示class的区别就是,不显示class就是一个普通的json串,jackson反序列化时会生成一个LinkedHashMap对象,显示class时json传里会带上class全路径的信息,jackson反序列化会生成对应的类对象。
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory, Jackson2ObjectMapperBuilder builder) {
ObjectMapper objectMapper = new ObjectMapper();
builder.configure(objectMapper);
objectMapper = objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY);
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(RedisSerializer.string());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer(objectMapper));
redisTemplate.setConnectionFactory(redisConnectionFactory);
return redisTemplate;
}
几个细节
1 如果这里不用 new GenericJackson2JsonRedisSerializer(objectMapper) 而是用 RedisSerializer.json(),也是同样可以显示class信息的,但是他有个问题,就是系统设置的自定jsonIgonre等注解没法用,这个在为什么序列化无效里讲过
所以必须用全局配置过的objectMapper
2 为什么不用objectMapper的bean,因为这个bean是spring定义的,用来spring mvc序列化等,他的配置就是不可以显示类信息,否则抛送给前端有安全风险。所以用spring的objectMapperBuilder重新配置了一个ObjectMapper,即
builder.configure(objectMapper);
这行代码,
然后用显示类信息的配置覆盖了原有配置,即
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY);
这行代码
3 为什么非得带上类信息,因为redis经常需要复杂对象序列化反序列化,如果没有类信息的话会被反序列化为LinkedHashMap