GenericJackson2JsonRedisSerializer 和 Jackson2JsonRedisSerializer

配置 Redis 缓存 RedisConfig 时,可能会用到两个序列化类:GenericJackson2JsonRedisSerializerJackson2JsonRedisSerializer ,哪这两种分别有什么区别,怎么使用呢?

它俩都是针对序列化和反序列化的。序列化过程,将对象转成 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);

参考:‘enableDefaultTyping(com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping)’ is deprecated in RedisConfig

本文由老郭种树原创,转载请注明:https://guozh.net/genericjackson2jsonredisserializer-vs-jackson2jsonredisserializer/

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注