问题背景
A服务写入Redis的数据,B服务读出后,value值多了个双引号。
如 “String” 获取到的是 ““String””
问题原因
A服务添加了一个redisTemplate Bean配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | @Configuration public class RedisTemplateConfig { @Bean (name = "redisTemplate" ) public RedisTemplate setRedisTemplate(RedisConnectionFactory redisConnectionFactory, RedisProperties redisProperties) { StringRedisTemplate template = new StringRedisTemplate(redisConnectionFactory); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object. class ); redisProperties.setPassword(SecretKeyClient.getPassword( System.getProperty( "datakeeper.application.redis.community.key_name" ))); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); template.setValueSerializer(jackson2JsonRedisSerializer); template.setHashValueSerializer(jackson2JsonRedisSerializer); template.afterPropertiesSet(); return template; } } |
我们可以看到ValueSerializer用的是jackson2JsonRedisSerializer。
使用的时候通过@Resource注解引入:
1 2 | @Resource private RedisTemplate redisTemplate; |
@Resource默认就是通过beanName注入的,所以此时注入的RedisTemplate就是我们上面配置的。
在B服务中:
也配置了这样一个RedisTemplate:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | @Configuration public class RedisTemplateConfig { @Bean (name = "redisTemplate" ) public RedisTemplate setRedisTemplate(RedisConnectionFactory redisConnectionFactory, RedisProperties redisProperties) { StringRedisTemplate template = new StringRedisTemplate(redisConnectionFactory); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object. class ); redisProperties.setPassword(SecretKeyClient.getPassword( System.getProperty( "datakeeper.application.redis.community.key_name" ))); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); template.setValueSerializer(jackson2JsonRedisSerializer); template.setHashValueSerializer(jackson2JsonRedisSerializer); template.afterPropertiesSet(); return template; } } |
配置和A服务一模一样。
但是,在使用RedisTemplate时采用的@Autowired注解:
1 2 | @Autowired private RedisTemplate redisTemplate; |
我们知道@Autowired注解默认是按照BeanClass即BeanType进行注入的,此时注入的RedisTemplate却不是我们上面配置的,而是SpringBoot自动配置的。
在RedisAutoConfiguration中:
1 2 3 4 5 6 7 8 | @Bean @ConditionalOnMissingBean (name = "redisTemplate" ) public RedisTemplate<object data-origwidth= "" data-origheight= "" style= "width: 1264px;" > redisTemplate( RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { RedisTemplate<object data-origwidth= "" data-origheight= "" style= "width: 631px;" > template = new RedisTemplate(); template.setConnectionFactory(redisConnectionFactory); return template; }</object></object> |
我们看到,我们配置的与SpringBoot默认的redisTemplate不相同。
通过打断点进行对比:
SpringBoot默认的:
我们自己定义的:
可以看到,在valueSerializer上,一个是StringRedisSerializer,一个是Jackson2JsonRedisSerializer。
所以,在序列化与反序列化的方式不同时,产生这种乱码,奇怪的双引号问题也就可以解释了。
解决方案
将序列化反序列化方式改成一致。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持IT俱乐部。