Springboot 项目使用 RMapCache 保存数据,发现值出现 \x00,如何处理?

Springboot 项目使用 RMapCache 保存数据,发现值出现 \x00

image.png
\#1 使用 StringRedisTemplate 保存数据,可用
\#2 使用 RMapCache 保存数据, 出现\x00, 不可用

大致结构如下
demo project
源码自取
测试视频
springboot: 2.7.18
redisson: 3.26.1 / 3.21.0
redis: Redis-x64-5.0.14.1 / redis-5.0.5

redisson codec: JsonJacksonCodec / StringCodec

跟踪代码后发现,数据在执行lua脚本后出现了问题
image.png
然后将脚本放到 redis-cli 直接执行,数据也是异常的

eval "return struct.pack('dLc0', 0, string.len(ARGV[1]), ARGV[1])" 0 "test"

image.png

我要怎么修改

===== 关于 RedisTemplate 序列化回复 =====
我不知道为啥回复,刷新之后就消失了,再回复又重复,删除又两个都消失,在这里回复吧。

我并不是使用 RedisTemplate 来操作,而是使用的是 Redisson 的 RedissonClient 来进行操作
成功案例:直接使用 StringRedisTemplate ,demo 项目懒得配那么多,而且我也是成功了,上图#1
失败案例:使用 RMapCache<String, String> mapCache = redissonClient.getMapCache(name);

我的错误发生在 使用 mapCache.put(key, value) 后
如果要设置,也是设置 redissonClient 的 Codec,我尝试过 JsonJacksonCodec 和 StringCodec,没有效果。原因,原问题有解释
===== 关于 RedisTemplate 序列化回复 =====

阅读 1.6k
avatarAI BotBETA

首先,让我们来分析这个问题。

从你给出的信息中,当使用 RMapCache 保存数据时,值中出现了 \x00。这很可能是由于编码问题导致的。\x00 是一个特殊的字符,在 Redis 中通常用作命令的分隔符。

以下是一些建议的解决步骤:

  1. 检查序列化/反序列化:确保你使用的是正确的序列化/反序列化方式。JsonJacksonCodecStringCodec 都可以工作,但要确保它们与你的数据结构兼容。
  2. Lua 脚本问题:你提到在执行 Lua 脚本后数据出现了问题。Lua 脚本在 Redis 中执行时,它会接收一个或多个参数,并且返回一个或多个结果。确保 Lua 脚本正确处理了参数,并返回了预期的结果。
  3. 编码问题:考虑使用 StringRedisTemplate 来保存数据,因为它是为字符串设计的,可能避免了编码问题。如果你必须使用 RMapCache,确保你了解其内部的工作原理,并考虑使用其他序列化/反序列化方式。
  4. 版本兼容性:确保你的 Spring Boot、Redisson 和 Redis 的版本是兼容的。有时,库的新版本可能修复了旧版本中的问题。
  5. 日志和调试:增加日志记录,特别是与序列化、反序列化和 Lua 脚本执行相关的部分。这可以帮助你更好地理解问题所在。
  6. 社区和文档:查看 Redisson 的官方文档和社区论坛,看看是否有其他人遇到了类似的问题,或者是否有新的解决方案。
  7. 简化问题:尝试创建一个简化的示例项目,只包含最基本的设置和功能,看是否还会出现相同的问题。这可以帮助你确定问题是特定于你的项目配置还是更普遍的问题。

希望这些建议能帮助你解决问题!如果你有更多的代码或错误信息,也可以提供给我,我会尽量为你提供更具体的帮助。

1 个回答

RedisTemplate 如果不主动设置,默认使用的都是 JdkSerializationRedisSerializer,换成 GenericJackson2JsonRedisSerializer 就好了。

@Configuration
public class RedisTemplateConfig {
    @Bean
    public RedisTemplate redisTemplate() {
        redisTemplate.setDefaultSerializer(new GenericJackson2JsonRedisSerializer());
        return redisTemplate;
    }
}

或者

@Configuration
public class RedisTemplateConfig {
    @Bean
    public GenericJackson2JsonRedisSerializer springSessionDefaultRedisSerializer() {
        return new GenericJackson2JsonRedisSerializer();
    }
}

补充

import com.fasterxml.jackson.databind.ObjectMapper;
import org.redisson.client.codec.Codec;
import org.redisson.codec.JsonJacksonCodec;
import org.redisson.spring.starter.RedissonAutoConfiguration;
import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RedissonCustomizer {
    @Bean
    RedissonAutoConfigurationCustomizer redissonCustomizer()  {
        ObjectMapper objectMapper = new ObjectMapper();

        return configuration -> {
            Codec codecIns = new JsonJacksonCodec(objectMapper);
            configuration.setCodec(codecIns);
        };
    }
}

更新

用mapCache,是一定有这些特殊字符的,cache有最大存活时间。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏