zoukankan      html  css  js  c++  java
  • redis使用Jackson2JsonRedisSerializer序列化问题

    一、spring boot 集成Redis方法

    • 依赖
    <!--redis-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
    </dependency>
    View Code
    • Redis自定义序列化
    @Configuration
    public class RedisConfig {
    
    
        @Bean(name = "strRedisTemplate")
        public RedisTemplate<String, String> strRedisTemplate(RedisConnectionFactory factory) {
            RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
            redisTemplate.setConnectionFactory(factory);
    
            // 使用Jackson2JsonRedisSerialize 替换默认序列化(默认采用的是JDK序列化)
            Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
            ObjectMapper om = new ObjectMapper();
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jackson2JsonRedisSerializer.setObjectMapper(om);
    
            redisTemplate.setKeySerializer(jackson2JsonRedisSerializer);
            redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
            redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer);
            redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
            return redisTemplate;
        }
    
        @Bean(name = "intRedisTemplate")
        public RedisTemplate<String, Integer> intRedisTemplate(RedisConnectionFactory factory) {
            RedisTemplate<String, Integer> redisTemplate = new RedisTemplate<>();
            redisTemplate.setConnectionFactory(factory);
    
            // 使用Jackson2JsonRedisSerialize 替换默认序列化(默认采用的是JDK序列化)
            Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
            ObjectMapper om = new ObjectMapper();
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jackson2JsonRedisSerializer.setObjectMapper(om);
    
            redisTemplate.setKeySerializer(jackson2JsonRedisSerializer);
            redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
            redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer);
            redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
            return redisTemplate;
        }
    
    }
    View Code
    • 使用代码
    @Service
    public class RedisServiceImpl implements IRedisService {
    
        @Resource(name = "intRedisTemplate")
        private RedisTemplate<String, Integer> intTemplate;
        @Resource(name = "strRedisTemplate")
        private RedisTemplate<String, String> strTemplate;
    
        @Override
        public void incrHash(String key, String field, Integer value) {
            intTemplate.opsForHash().increment(key, field, value);
        }
    
        @Override
        public void incrKey(String key, Integer value) {
            if(null == key || null == value){
                return;
            }
            intTemplate.opsForValue().increment(key,value);
        }
    
        @Override
        public Integer getInteger(String key) {
            if(null == key){
                return null;
            }
            return intTemplate.opsForValue().get(key);
        }
    }
    View Code

    五、出现问题  

      使用的时候,发现一个问题,如果我用IntegerTemplate存储值到Redis,会进行序列化,自动为String类型的键和值添加双引号,这是Jackson2JsonRedisSerializer特性,但是使用StringTemplate,存储的String类型的键和值都不带双引号

    六、几种序列化对比

    这是别人总结的Redis常见的几种序列化方式特性,详细见:参考文章

    以下内容引用别人博客

    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    我们这里针对StringRedisSerializer,Jackson2JsonRedisSerializer和JdkSerializationRedisSerializer进行测试。

    下面是,把3种Serializer保存到Redis中的结果:

    1,所有的KeySerializer和HashKeySerializer都使用StringRedisSerializer,用其它Serializer的没有什么意义,就像最上面的例子一样。
    2,上面序列化后的值,是保存到redis中的值,从Redis中读取回Java中后,值的内容都是一样的。

    从上面的结果不难看出,

    1,用StringRedisSerializer进行序列化的值,在Java和Redis中保存的内容是一样的

    2,用Jackson2JsonRedisSerializer进行序列化的值,在Redis中保存的内容,比Java中多了一对双引号。

    3,用JdkSerializationRedisSerializer进行序列化的值,对于Key-Value的Value来说,是在Redis中是不可读的。对于Hash的Value来说,比Java的内容多了一些字符。

    (如果Key的Serializer也用和Value相同的Serializer的话,在Redis中保存的内容和上面Value的差异是一样的,所以我们保存时,只用StringRedisSerializer进行序列化)

    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    七、问题原因

    出现“存储Integer类型数据,自动序列化(加双引号),存储String类型,序列化失败(没有双引号)”的原因是:

    我在设置自定义序列化的时候,为Bean起了个名称叫:"StringRedisTemplate",这个名称和StringRedisTemplate重名了,spring注入的时候,注入的是StringRedisTemplate,不是我更改过序列化方式后的Template对象。

     @Bean(name = "stringRedisTemplate")
        public RedisTemplate<String, String> strRedisTemplate(RedisConnectionFactory factory) {
            RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
            redisTemplate.setConnectionFactory(factory);
    
            // 使用Jackson2JsonRedisSerialize 替换默认序列化(默认采用的是JDK序列化)
            Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
            ObjectMapper om = new ObjectMapper();
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jackson2JsonRedisSerializer.setObjectMapper(om);
    
            redisTemplate.setKeySerializer(jackson2JsonRedisSerializer);
            redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
            redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer);
            redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
            return redisTemplate;
        }

    真是个傻逼错误

  • 相关阅读:
    84. Largest Rectangle in Histogram (Solution 2)
    84. Largest Rectangle in Histogram (Solution 1)
    73. Set Matrix Zeroes
    【JavaScript】Symbol 静态方法
    【JavaScript】Date
    【JavaScript】Math
    725. Split Linked List in Parts把链表分成长度不超过1的若干部分
    791. Custom Sort String字符串保持字母一样,位置可以变
    508. Most Frequent Subtree Sum 最频繁的子树和
    762. Prime Number of Set Bits in Binary Representation二进制中有质数个1的数量
  • 原文地址:https://www.cnblogs.com/donfaquir/p/10594199.html
Copyright © 2011-2022 走看看