SpringBoot中的RedisTemplate的序列化

发布时间 2023-04-19 17:03:53作者: gengone

在SpringBoot的项目中,可以通过引入spring-data-redis包来获得对redis的支持,其中RedisTemplate又是使用这些API的入口。在pom文件可以通过如下代码引入spring对redis的支持:

点击查看代码
  ```
  <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-data-redis</artifactId>
  </dependency>
  ```
  1. 使用RedisTemplate可能遇到的问题
    参见如下的代码,使用RedisTemplate看起来很正常,但是使用StringRedisTemplate来获取的时候出现了一些奇怪的问题,先看代码:
点击查看代码
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Test
    public void test1(){
       redisTemplate.opsForValue().set("key1","value1");
       System.out.println("********"+redisTemplate.opsForValue().get("key1")+"*******");
       System.out.println("########"+stringRedisTemplate.opsForValue().get("key1")+"#######");
    }

结果如下:

可以看出通过RedisTemplate设置的key1在客户端中变成了乱码。接下来我们再试下通过StringRedisTemplate设置key1的情况:

点击查看代码
@Test
    public void test2(){
        stringRedisTemplate.opsForValue().set("key1","value2");
        System.out.println("********"+redisTemplate.opsForValue().get("key1")+"*******");
        System.out.println("########"+stringRedisTemplate.opsForValue().get("key1")+"#######");
    }

结果如下(黑色为程序结果,白色为客户端结果):

通过StringRedisTemplate设置的key1看起来显示正常。造成这一切的原因就是RedisTempalte使用的序列化和反序列化机制。

  • RedisTemplate的序列化机制
    RedisTemplate默认使用JDK的序列化机制,因此从程序中输入的字符串经过序列化看起来像是乱码;而StringRedisTemplate使用了String的序列化机制,因此有一种所见即所得的效果。
  • 何时使用RedisTemplate,何时使用StringRedisTemplate
    当只使用简单的字符串时,使用StringRedisTemplate; 当使用复杂对象的时候,使用RedisTemplate
  • 设置RedisTemplate的序列化机制
    使用JDK默认的序列化机制并不友好,因此有必要再使用RedisTemplate设置其序列化方式。
    以下为设置RedisTemplate序列化机制的代码,使用了Jackson2JsonRedisSerializer,设置了key-value和hash key-value的序列化。
点击查看代码
@Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

        //设置key-value的序列化
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);

        //设置hash key-value的序列化
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);

        redisTemplate.setEnableTransactionSupport(true);

        redisTemplate.afterPropertiesSet();

        return redisTemplate;
    }
  • 最后测试一下
    测试代码
点击查看代码
@Test
    public void test1(){
       redisTemplate.opsForValue().set("key11","value11");
       System.out.println("********"+redisTemplate.opsForValue().get("key11")+"*******");
       System.out.println("########"+stringRedisTemplate.opsForValue().get("key11")+"#######");
    }

这次直接看客户端的值,可以看到通过RedisTemplate设置的key-value已经能够给正常显示了。