Redis序列化反序列化不一致導(dǎo)致String類型值多了雙引號(hào)問題
問題背景
A服務(wù)寫入Redis的數(shù)據(jù),B服務(wù)讀出后,value值多了個(gè)雙引號(hào)。
如 “String” 獲取到的是 ““String””
問題原因
A服務(wù)添加了一個(gè)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。
使用的時(shí)候通過@Resource注解引入:
@Resource
private RedisTemplate<String, String> redisTemplate;@Resource默認(rèn)就是通過beanName注入的,所以此時(shí)注入的RedisTemplate就是我們上面配置的。
在B服務(wù)中:
也配置了這樣一個(gè)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時(shí)采用的@Autowired注解:
@Autowired
private RedisTemplate<String, String> redisTemplate;我們知道@Autowired注解默認(rèn)是按照BeanClass即BeanType進(jìn)行注入的,此時(shí)注入的RedisTemplate卻不是我們上面配置的,而是SpringBoot自動(dòng)配置的。
在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上,一個(gè)是StringRedisSerializer,一個(gè)是Jackson2JsonRedisSerializer。
所以,在序列化與反序列化的方式不同時(shí),產(chǎn)生這種亂碼,奇怪的雙引號(hào)問題也就可以解釋了。
解決方案
將序列化反序列化方式改成一致。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Redis集群節(jié)點(diǎn)通信過程/原理流程分析
這篇文章主要介紹了Redis集群節(jié)點(diǎn)通信過程/原理,詳細(xì)介紹了Cluster(集群)的節(jié)點(diǎn)通信的流程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03
基于Redis實(shí)現(xiàn)阻塞隊(duì)列的方式
本文主要講解基于?Redis?的方式實(shí)現(xiàn)異步隊(duì)列,基于?Redis?的?list?實(shí)現(xiàn)隊(duì)列的方式也有多種,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2021-12-12
windows環(huán)境下Redis+Spring緩存實(shí)例講解
這篇文章主要為大家詳細(xì)介紹了windows環(huán)境下Redis+Spring緩存實(shí)例教程,感興趣的小伙伴們可以參考一下2016-04-04
redis5.0以上基于密碼認(rèn)證的集群cluster方式
這篇文章主要介紹了redis5.0以上基于密碼認(rèn)證的集群cluster方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11
大白話講解調(diào)用Redis的increment失敗原因及推薦使用詳解
本文主要介紹了調(diào)用Redis的increment失敗原因及推薦使用,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11

