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

 更新时间:2024年08月20日 14:28:36   作者:c&0xff00  
这篇文章主要介绍了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 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注解引入:

    @Resource
    private 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.setObjectMapper(om);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        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默认的:

我们自己定义的:

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

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

解决方案

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

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Redis面试必备之缓存设计规范与性能优化详解

    Redis面试必备之缓存设计规范与性能优化详解

    你是否在使用Redis时,不清楚Redis应该遵循的设计规范而苦恼,你是否在Redis出现性能问题时,不知道该如何优化而发愁,快跟随小编一起学习起来吧
    2024-03-03
  • 推荐一款神仙颜值的 Redis 客户端工具(速收藏)

    推荐一款神仙颜值的 Redis 客户端工具(速收藏)

    这篇文章主要给大家推荐一款神仙颜值的 Redis 客户端工具(速收藏),非常好用的redis桌面管理工具,可以运行于Linux、Windows、Mac三大平台,并且当加载大数量的key不会crash,感兴趣的朋友跟随小编一起看看吧
    2020-12-12
  • Django使用redis配置缓存的方法

    Django使用redis配置缓存的方法

    Redis是一个内存数据库由于其性能极高,因此经常作为中间件、缓存使用,缓存某些内容是为了保存昂贵计算的结果,这样就不必在下次执行计算,接下来通过本文给大家分享redis配置缓存的方法,感兴趣的朋友一起看看吧
    2021-06-06
  • Windows系统设置Redis服务使其开机自启动

    Windows系统设置Redis服务使其开机自启动

    Redis是一种键值对数据库,也称为内存数据库,因为它可以将数据存储在内存中,而不是在磁盘上,下面这篇文章主要给大家介绍了关于Windows系统设置Redis服务使其开机自启动的相关资料,需要的朋友可以参考下
    2024-01-01
  • Redis中 HyperLogLog数据类型使用小结

    Redis中 HyperLogLog数据类型使用小结

    Redis使用HyperLogLog的主要作用是在大数据流(view,IP,城市)的情况下进行去重计数,这篇文章主要介绍了Redis中 HyperLogLog数据类型使用总结,需要的朋友可以参考下
    2023-03-03
  • redis的string类型及bitmap介绍

    redis的string类型及bitmap介绍

    这篇文章主要介绍了redis的string类型及bitmap介绍,redis有很多的客户端连接进来,站在redis所在机器的角度来说,就是有很多socket的连接
    2022-07-07
  • 使用Redis实现延时任务的解决方案

    使用Redis实现延时任务的解决方案

    这篇文章主要介绍了使用Redis实现延时任务的解决方案,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-08-08
  • 带你轻松掌握Redis分布式锁

    带你轻松掌握Redis分布式锁

    这篇文章主要介绍了带你轻松掌握Redis分布式锁,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • 基于redis 7.2.3的makefile源码解读学习

    基于redis 7.2.3的makefile源码解读学习

    这篇文章主要为大家介绍了基于redis 7.2.3的makefile源码解读学习,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • redis和redisson实现分布式锁的操作方法

    redis和redisson实现分布式锁的操作方法

    使用 Redis 实现分布式锁,最直接的想法是利用 setnx 和 expire 命令实现加锁,这篇文章主要介绍了redis和redisson实现分布式锁的操作方法,需要的朋友可以参考下
    2024-03-03

最新评论