SpringBoot中的RedisTemplate的序列化

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

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

    使用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的情况:

    StringRedisTemplate设置和获取的情况
    @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使用的序列化和反序列化机制。

  1. RedisTemplate的序列化机制
    RedisTemplate默认使用JDK的序列化机制,因此从程序中输入的字符串经过序列化看起来像是乱码;而StringRedisTemplate使用了String的序列化机制,因此有一种所见即所得的效果。

  2. 何时使用RedisTemplate,何时使用StringRedisTemplate
    当只使用简单的字符串时,使用StringRedisTemplate; 当使用复杂对象的时候,使用RedisTemplate

  3. 设置RedisTemplate的序列化机制
    使用JDK默认的序列化机制并不友好,因此有必要再使用RedisTemplate设置其序列化方式。
    以下为设置RedisTemplate序列化机制的代码,使用了Jackson2JsonRedisSerializer,设置了key-value和hash key-value的序列化。

    配置RedisTemplate序列化机制
    @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;
    	}
    
  4. 最后测试一下

    测试代码
    @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已经能够给正常显示了。

posted @ 2023-04-19 16:56  gengone  阅读(247)  评论(0编辑  收藏  举报