0%

Spring Boot RedisTemplate使用心得

Spring Boot提供了很人性化的redis bean RedisTemplate,可默认的key value 可读性不怎么好

  • RedisTemplate的key序列化使用JdkSerializationRedisSerializer,所以key会带上类信息的乱码,导致key值可读性差
    • RedisTemplate.class afterPropertiesSet()
      1
      2
      3
       if (this.defaultSerializer == null) {
      this.defaultSerializer = new JdkSerializationRedisSerializer(this.classLoader != null ? this.classLoader : this.getClass().getClassLoader());
      }
    • 初始化的key就是这样的,在实际的key前面加入了序列化后的类信息,造成key值可读性变差
      1
      2
      20050) "\xac\xed\x00\x05t\x00ECOMMENT_ID:4726_STATUS:0_TYPE:0_UUID:0d43e283bef011e782656c92bf471308"
      20051) "\xac\xed\x00\x05t\x00ECOMMENT_ID:8246_STATUS:0_TYPE:0_UUID:02dbce08bef011e782656c92bf471308"
    • 修改redisTemplate的默认序列化方法为StringRedisSerializer
      1
      2
      3
      4
      5
      6
      7
      8
      9
      @Bean
      RedisTemplate getRedisTemplate(RedisTemplate redisTemplate) {
      //redistemplate原生中key是用JdkSerializationRedisSerializer
      //会引入类信息导致key值不可读
      //把key序列化方法改成string的就解决了这个问题
      StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
      redisTemplate.setKeySerializer(stringRedisSerializer);
      redisTemplate.setHashKeySerializer(stringRedisSerializer);
      }
    • 修改redisTemplate后,在redis中存的key值就变成可读性强的字符串
      1
      2
      20059) "COMMENT_ID:7365_STATUS:0_TYPE:0_UUID:02808b75bef011e782656c92bf471308"
      20060) "COMMENT_ID:5365_STATUS:0_TYPE:0_UUID:021c38e9bef011e782656c92bf471308"
  • RedisTemplate默认value序列化可读性很差
    • value可读性很差
    • 修改redisTemplate的value序列化方法
      • 实现RedisSerializer接口的方法有几个,springboot默认使用的json工具是jackson,jackson实现类有两个GenericJackson2JsonRedisSerializerJackson2JsonRedisSerializer,两个都可以选择设置objectMapper,这样可以将配置文件中设置的json格式同步到redis的序列化json格式(比如时间格式),但使用Jackson2JsonRedisSerializer反序列化出现了问题,所以这里选择GenericJackson2JsonRedisSerializer
      • 光设置了GenericJackson2JsonRedisSerializer,反序列化也是会出问题,因为序列化时没有带入类信息,进行泛型转换时会报出java.util.LinkedHashMap cannot be cast to xxx的错误,因为此时从redis取出来的数据结构是LinkedHashMap,所以objectMapper需要设置保留类型enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL)
      • 把Spring Boot的objectMapper Bean设置了默认类型,会导致Spring Boot的@RequestBody报错Unexpected token (START_OBJECT), expected START_ARRAY错误,所以不能直接修改objectMapper,需要克隆一份来设置,幸好objectMapper提供了copy方法
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
         @Bean
        RedisTemplate getRedisTemplate(RedisTemplate redisTemplate) {
        //使redis中的value存入json对象,所以使用bean中的objectMapper
        //不改变objectMapper的属性,因为全局的objectMapper设置了enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL))
        //会导致@RequestBody出现Unexpected token (START_OBJECT), expected START_ARRAY错误
        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer =
        new GenericJackson2JsonRedisSerializer(objectMapper.copy().enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL));
        redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
        redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);
        return redisTemplate;
        }
    • 发现value可读性好了许多,但中文部分显示会出现异常
    • 平常进入redis客户端的命令是redis-cli,要想正常显示中文,得用redis-cli --raw

总结:
将redisTemplate的key序列化方式设置为StringRedisSerializer可增加key可读性,将value序列化方式设置为GenericJackson2JsonRedisSerializer,可将存到redis中的json value格式同步为系统的配置,增加value可读性.