关于在SpringBoot中使用RedisTemplate序列化的一些问题
在日常的项目中redis已经成为必不可少的一部分,本人以前redis用的不是很多,并且用的是redis的jedis实现。最近,想着在SpringBoot中使用redis,之前做过一些了解但是没有具体用过,这次具体实践的时候发现了一些小问题,在此记录一下。
本人使用的SpringBoot版本为2.1.13.RELEASE,SpringBoot 2.X版本以后集成的redis为Luttuce实现。在使用的过程中先添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
添加配置
spring:
redis:
host: localhost
password:
port: 6379
测试
@RestController public class RedisController { @Autowired private RedisTemplate redisTemplate; @GetMapping("/testForString") public String testForString(){ redisTemplate.opsForValue().set("name","zhangsan"); Object name = redisTemplate.opsForValue().get("name"); System.out.println("name:"+name); return "success"; } }
说明执行成功,我们通过redis客户端看下数据
通过keys *(不建议使用,自己测试用的)查看,发现存key为\xac\xed\x00\x05t\x00\x04name的数据
\xac\xed\x00\x05t\x00\x04name对应的值为\xac\xed\x00\x05t\x00\bzhangsan
由上可以看出数据是存到了redis中,只不过在存入的过程中做了一定处理。网上查了一下是序列化的问题,RedisTemplate的keySerializer和valueSerializer默认使用的是JdkSerializationRedisSerializer,此处我们需要重新设置一下keySerializer和valueSerializer
网上随便搜了下方法,有如下方法
@Bean public RedisTemplate<Object, Object> redisTemplateKeyObject(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); objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; }
再次执行测试方法,发现没有效果。我们打断点跟一下代码
发现设置没生效。网上查了下应该是自动配置导致了,找到Redis自动配置类看了下
@ConditionalOnMissingBean(name = {"redisTemplate"})
当找不到name为redisTemplate的Bean时会自动注入RedisTemplate。在看下我们上面设置RedisTemplate的代码,发现对应的name为redisTemplateKeyObject,我们将其修改一下
@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); objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; }
现在可以通过redis客户端查看数据了。以上就是自己使用RedisTemplate的一次实践,其中遇到了一些小问题,在此记录一下。