根本原因在于RedisTemplate默认使用JdkSerializationRedisSerializer,将字符串包装为String对象再序列化成带魔数的二进制流,导致redis-cli直接解析显示\xac\xed\x00\x05等乱码;应优先使用预设StringRedisSerializer的StringRedisTemplate存字符串,或显式配置RedisTemplate的key/value及hash相关序列化器为StringRedisSerializer或Jackson2JsonRedisSerializer。

根本原因在于 RedisTemplate 默认用 JdkSerializationRedisSerializer,它把字符串(比如 "用户登录成功")包装成 String 对象再整个序列化成二进制字节流,不是纯 UTF-8 文本。redis-cli 读出来时直接当字节解析,自然显示乱码或十六进制。
优先用 StringRedisTemplate 存字符串
90% 的场景只是存取字符串(如 token、缓存 HTML 片段、计数器值),直接用 StringRedisTemplate 就行 —— 它内部已预设 StringRedisSerializer,默认 UTF-8 编码,开箱即用,零配置不乱码。
@Autowired StringRedisTemplate stringRedisTemplate;- 调用
stringRedisTemplate.opsForValue().set("key", "你好"),redis-cli 中get key显示正常中文 - 注意:它只能操作
String类型,不能直接存 Map 或自定义对象
必须用 RedisTemplate 时,重点配 setValueSerializer
如果你需要存 Map、List、实体类等复杂类型,又希望其中的字符串字段(比如 JSON 字符串)可读不乱码,关键不是改 key,而是明确设置 value 的序列化器为 StringRedisSerializer。
-
template.setKeySerializer(new StringRedisSerializer())—— 让 key 可读(如 "user:1001") template.setValueSerializer(new StringRedisSerializer())</strong></li> <li><code>template.setHashKeySerializer(new StringRedisSerializer())
-
template.setHashValueSerializer(new StringRedisSerializer())—— 哈希结构里的 value 也要设,否则 hgetall 仍可能乱码
想存对象并保持可读?用 Jackson 序列化为 JSON
如果要存 User 对象这类 POJO,又希望 redis 中看到的是明文 JSON(如 {"id":1,"name":"张三"}),推荐 Jackson2JsonRedisSerializer 或 GenericJackson2JsonRedisSerializer:
立即学习“Java免费学习笔记(深入)”;
- value 序列化器换成
new Jackson2JsonRedisSerializer<>(User.class),反序列化才准确 - 建议搭配
ObjectMapper禁用空 Bean 报错:mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS) - 注意:JSON 序列化对字段名大小写、驼峰规则敏感,需统一命名风格或配置可见性
别踩这些坑
常见错误配置导致乱码反复出现:
- 只配了
setKeySerializer,漏掉setValueSerializer—— 这是最高频失误 - 用了
GenericJackson2JsonRedisSerializer却没指定泛型类型,反序列化时无法还原对象 - 在 Spring Boot 2.0+ 中手动 new RedisTemplate 却忘了调
afterPropertiesSet(),部分配置不生效 - 混合使用
RedisTemplate和StringRedisTemplate操作同一个 key,序列化方式冲突


















