配置 Redis 缓存 RedisConfig
时,可能会用到两个序列化类:GenericJackson2JsonRedisSerializer
和Jackson2JsonRedisSerializer
,哪这两种分别有什么区别,怎么使用呢?
它俩都是针对序列化和反序列化的。序列化过程,将对象转成 Json 字符串,Jackson2JsonRedisSerializer
正常转换。
User user = new User();
user.setAppId("laoguo");
user.setPassword("12345666");
redisTemplate.opsForValue().set("user", user);
保存后结果:
{\"appId\":\"laoguo\",\"password\":\"12345666\"}
但如果使用GenericJackson2JsonRedisSerializer
,序列化将对象转成 Json 后,会附加 @class
属性,该属性的值是对象包名路径。
{\"@class\":\"com.guozh.blogdemo.User\",\"appId\":\"laoguo\",\"password\":\"12345666\"}
这是它俩序列化的区别,反序列化也一样有区别,也就是将 Json 字符串转成对象的过程。
如果使用Jackson2JsonRedisSerializer
,你会发现取对象时(反序列化)就会报错。
User user1 = (User) redisTemplate.opsForValue().get("user");
java.util.LinkedHashMap cannot be cast to **
但GenericJackson2JsonRedisSerializer
没问题,可以任意存取,不会报错。
如果想解决前面的报错,需要配置 default typing
。
objectMapper.enableDefaultTyping(DefaultTyping.NON_FINAL, As.PROPERTY);
完整代码
ObjectMapper om = new ObjectMapper();
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
jackson2JsonRedisSerializer.setObjectMapper(om);
但这个方法enableDefaultTyping
已经被过期,因为有安全漏洞Jackson-databind引发的漏洞问题分析。
从我找到的文章来看,目前推荐使用
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY);
替换
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
本文由老郭种树原创,转载请注明:https://guozh.net/genericjackson2jsonredisserializer-vs-jackson2jsonredisserializer/