Redis序列化反序列化不一致導(dǎo)致String類型值多了雙引號問題
問題背景
A服務(wù)寫入Redis的數(shù)據(jù),B服務(wù)讀出后,value值多了個雙引號。
如 “String” 獲取到的是 ““String””
問題原因
A服務(wù)添加了一個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默認(rèn)就是通過beanName注入的,所以此時注入的RedisTemplate就是我們上面配置的。
在B服務(wù)中:
也配置了這樣一個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服務(wù)一模一樣。
但是,在使用RedisTemplate時采用的@Autowired注解:
@Autowired private RedisTemplate<String, String> redisTemplate;
我們知道@Autowired注解默認(rèn)是按照BeanClass即BeanType進(jìn)行注入的,此時注入的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默認(rèn)的redisTemplate不相同。
通過打斷點(diǎn)進(jìn)行對比:
SpringBoot默認(rèn)的:
我們自己定義的:
可以看到,在valueSerializer上,一個是StringRedisSerializer,一個是Jackson2JsonRedisSerializer。
所以,在序列化與反序列化的方式不同時,產(chǎn)生這種亂碼,奇怪的雙引號問題也就可以解釋了。
解決方案
將序列化反序列化方式改成一致。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Redis面試必備之緩存設(shè)計規(guī)范與性能優(yōu)化詳解
你是否在使用Redis時,不清楚Redis應(yīng)該遵循的設(shè)計規(guī)范而苦惱,你是否在Redis出現(xiàn)性能問題時,不知道該如何優(yōu)化而發(fā)愁,快跟隨小編一起學(xué)習(xí)起來吧2024-03-03Windows系統(tǒng)設(shè)置Redis服務(wù)使其開機(jī)自啟動
Redis是一種鍵值對數(shù)據(jù)庫,也稱為內(nèi)存數(shù)據(jù)庫,因為它可以將數(shù)據(jù)存儲在內(nèi)存中,而不是在磁盤上,下面這篇文章主要給大家介紹了關(guān)于Windows系統(tǒng)設(shè)置Redis服務(wù)使其開機(jī)自啟動的相關(guān)資料,需要的朋友可以參考下2024-01-01Redis中?HyperLogLog數(shù)據(jù)類型使用小結(jié)
Redis使用HyperLogLog的主要作用是在大數(shù)據(jù)流(view,IP,城市)的情況下進(jìn)行去重計數(shù),這篇文章主要介紹了Redis中?HyperLogLog數(shù)據(jù)類型使用總結(jié),需要的朋友可以參考下2023-03-03基于redis 7.2.3的makefile源碼解讀學(xué)習(xí)
這篇文章主要為大家介紹了基于redis 7.2.3的makefile源碼解讀學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12redis和redisson實現(xiàn)分布式鎖的操作方法
使用 Redis 實現(xiàn)分布式鎖,最直接的想法是利用 setnx 和 expire 命令實現(xiàn)加鎖,這篇文章主要介紹了redis和redisson實現(xiàn)分布式鎖的操作方法,需要的朋友可以參考下2024-03-03