开发者

Redis序列化反序列化不一致导致String类型值多了双引号问题

目录
  • 问题背景
  • 问题原因
  • 解决方案
  • 总结

问题背景

A服务写入Redis的数据,B服务读出后,value值多了个双引号。

如 “String” 获取到的是 ““String””

问题原因

A服务添加了一个redisTemplate Bean配置:

@Configuration
public class RedisTemplateConfig {
    @Bean(name = "redisTemplate")
    public RedisTemplate setRedisTemplate(RedisConnectionFactory redisConnectionFactory, RedisProperties redisProperties) {
        StringRedisTemplate template = new StringRedisTemplate(redisConnectionFactory);
        Jackson2jsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2Jsowww.devze.comnRedisSerializer(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注解引入:

    @Resource
    priva编程客栈te RedisTemplate<String, String> redisTemplate;

@Resource默认就是通过beanName注入的,所以此时注入的RedisTemplate就是我们上面配置的。

在B服务中:

也配置了这样一个RedisTemplate:

@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.setObjectMapjavascriptper(om);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSwww.devze.comet();
        return template;
    }
}

配置和A服务一模一样。

但是,在使用RedisTemplate时采用的@Autowired注解:

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

我们知道@Autowired注解默认是按照BeanClass即BeanType进行注入的,此时注入的RedisTemplate却不是我们上面配置的,而是SpringBoot自动配置的。

在RedisAutoConfiguration中:

	@Bean
	@ConditionalOnMissingBean(name = "redisTemplate")
	public RedisTemplate<Object, Object> redisTemplate(
			RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
		RedisTemplate<Object, Object> template = new RedisTemplate<>();
		template.setConnectionFactory(redisConnectionFactory);
		return template;
	}

我们看到,我们配置的与SpringBoot默认的redisTemplate不相同。

通过打断点进行对比:

SpringBoot默认的:

Redis序列化反序列化不一致导致String类型值多了双引号问题

我们自己定义的:

Redis序列化反序列化不一致导致String类型值多了双引号问题

可以看到,在valueSerializer上,一个是StringRedisSerializer,一个是Jackson2JsonRedisSerializer。

所以,在序列化与反序列化的方式不同时,产生这种乱码,奇怪的双引号问题也就可以解释了。

解决方案

将序列化反序列化方式改成一致。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新数据库

数据库排行榜