大家好,我是一安~
问题
有两个服务:A
服务和 B
服务,A
服务负责将数据写入 Redis
的 Hash
中,B
服务负责从 Redis
中读取这些数据。在实际运行中,B
服务读取到的数字类型字符串与 A
服务写入的值不一致:
问题排查,最终发现通过hgetall
命令返回字符串多加了有引号:
这里怀疑可能是
Redis
配置中的序列化参数设置导致的
序列化与反序列化
Redis
序列化和反序列化是将数据结构转换为二进制格式和将二进制数据转换为对应的数据结构的过程。
序列化的作用是将数据结构转换为二进制形式,以便于传输和存储。它可以将数据保存在文件、数据库或者网络上,并能够被其他程序使用。序列化还能够对数据进行压缩,并提供灵活的数据交换格式。
反序列化则是将二进制数据转化为对应的数据结构,方便在
Redis
内部进行存储和查询等操作。这样可以实现对数据的读取和写入。
Redis
支持多种数据结构的序列化和反序列化,包括string、hash、list、set、zset
。
SpringBoot
提供了多种Redis
序列化方式,包括JDK
序列化、JSON
序列化、FastJSON
序列化、Jackson
序列化、Protobuf
序列化等。其中JDK
序列化是默认的序列化方式。
常见的序列化器
StringRedisSerializer
:用于字符串的序列化和反序列化。适用于简单的字符串键值对。Jackson2JsonRedisSerializer
:使用Jackson
库进行JSON
序列化和反序列化。适用于复杂对象的序列化。GenericJackson2JsonRedisSerializer
:类似于Jackson2JsonRedisSerializer
,但可以处理泛型对象。OxmMarshaler
:使用Spring
的Object-XML
映射功能进行序列化和反序列化。适用于XML
数据。GenericToStringSerializer
:将对象转换为字符串,适用于简单的对象。
A服务
使用了Jackson2JsonRedisSerializer
private RedisTemplate<String, Object> createRedisTemplate(JedisConnectionFactory connectionFactory) {
// 序列化配置
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance , ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setDefaultSerializer(jackson2JsonRedisSerializer);
redisTemplate.setEnableDefaultSerializer(true);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}复制
B服务
此服务为c++
端,使用默认String
,该端不做调整的话,修复A
端为new StringRedisSerializer()
方式
测试

使用StringRedisSerializer
来序列化key
和value
,这个序列化器会把Java
字符串直接转换为Redis
存储的字节序列,而不添加任何额外的格式化或引号。
使用Jackson2JsonRedisSerializer
来序列化key
和value
,会把Java
对象序列化为JSON
格式的字符串。如果你序列化的是Java
字符串,那么它就会被JSON
格式化,并在最终存储在Redis
中时带有双引号。
如果这篇文章对你有所帮助,或者有所启发的话,帮忙 分享、收藏、点赞、在看,你的支持就是我坚持下去的最大动力!