因为redistemplate默认使用jdkserializationredisserializer,将字符串序列化为含魔数\xac\xed的二进制流,导致redis-cli中显示乱码;需显式配置stringredisserializer等统一utf-8序列化器并清空旧数据才能解决。

为什么redis-cli里看到\xac\xed\x00\x05开头的key?
这不是Redis出问题,而是RedisTemplate默认用了JdkSerializationRedisSerializer——它把字符串当Java对象序列化,硬塞进魔数\xac\xed、版本号和类型标记。你用redis-cli get your_key直接读二进制流,当然显示乱码。
真正要命的是:这种格式只有同套JDK序列化器能反解,跨语言、跨工具、甚至换一个StringRedisTemplate都拿不到值。
- 别信控制台
System.out.println()输出,它受IDE或终端编码影响,先用redis-cli直连验证 -
StringRedisTemplate默认用StringRedisSerializer,天然UTF-8安全;但RedisTemplate不会自动继承这个行为 - 只要没显式配置
setKeySerializer和setValueSerializer,就还在走JDK那一套
如何让key和value在redis-cli里可读?
核心是统一用StringRedisSerializer,它只做UTF-8编解码,不加任何包装。但必须配全,漏一个就崩:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
template.setKeySerializer(new StringRedisSerializer())template.setValueSerializer(new StringRedisSerializer())- 哈希结构还得补上:
template.setHashKeySerializer(new StringRedisSerializer())和template.setHashValueSerializer(new StringRedisSerializer()) - 千万别混用
GenericJackson2JsonRedisSerializer配key——它会把"user:1"变成{"@class":"java.lang.String","value":"user:1"},key就不可读了
存JSON对象时该用哪个序列化器?
如果value是复杂对象(比如User),StringRedisSerializer会报错,这时得切到JSON方案,但要注意兼容性:
- 推荐
Jackson2JsonRedisSerializer(不是GenericJackson2JsonRedisSerializer),指定具体类型避免@class字段膨胀:new Jackson2JsonRedisSerializer(User.class) - key仍坚持用
StringRedisSerializer,保持可读性 - 如果项目要对接Go/Python服务,JSON是唯一靠谱选择;纯Java内部调用才考虑Kryo或Protobuf
- Spring Boot 3下,
Jackson2JsonRedisSerializer需手动注册ObjectMapper,否则中文可能被转义
为什么换了序列化器还是get不到值?
最常被忽略的点:旧数据没清空。Redis里存的是字节流,新序列化器无法解析旧格式。
- 上线前必须清空Redis库:
redis-cli FLUSHDB,否则新代码写入新格式,老数据还在那儿躺着 - 检查是否同时存在
RedisTemplate和StringRedisTemplate——它们序列化器不兼容,用A存的,B根本读不出来 - 泛型擦除陷阱:
RedisTemplate<string object></string>配了JSON序列化器,但业务代码传String进去,Jackson会把它包成"\"hello\""(带双引号),而不是裸字符串
真正的麻烦不在配置,而在数据迁移时没人记得删旧key。一串\xac\xed可能卡在缓存里半年,直到某次排查才发现它根本不是bug,只是历史残留。










