暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Redis 序列化值,多了双引号问题

一安未来 2024-11-11
16

大家好,我是一安~

问题

有两个服务: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
中时带有双引号。


如果这篇文章对你有所帮助,或者有所启发的话,帮忙 分享、收藏、点赞、在看,你的支持就是我坚持下去的最大动力!

对象与 Map 转换性能优化方案


如何设计一个通用的 Excel 导入导出功能


SpringBoot+Redis自定义注解实现发布订阅

文章转载自一安未来,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论