stringredistemplate乱码主因是序列化器被覆盖或未生效:自定义redistemplate未加@primary污染其配置,或手动new后未调用afterpropertiesset()及设置stringredisserializer(utf-8)。

乱码问题不是编码没设对,而是 StringRedisTemplate 默认用的序列化器在某些场景下被覆盖或未生效。只要确认它真正在用 StringRedisSerializer(UTF_8),基本不会乱码。
为什么 StringRedisTemplate 还会乱码
常见错误是:项目里定义了自定义 RedisTemplate Bean,但没加 @Primary,导致 Spring 自动装配时把 StringRedisTemplate 的底层 RedisConnectionFactory 实际交给了那个自定义模板去管理,结果它的序列化配置“污染”了 StringRedisTemplate 的行为。
另一个典型情况是手动 new 了一个 StringRedisTemplate(比如在工具类里),但没调用 afterPropertiesSet(),也没设置 valueSerializer,此时它退回到默认的 JdkSerializationRedisSerializer,就会出现 \xac\xed\x00\x05t\x00 开头的乱码。
- 用
redis-cli keys *查看 key 是"\xac\xed\x00\x05t\x00\x04name"→ 说明 value 被 JDK 序列化了 - key 显示为
{"@class":"java.lang.String","value":"xxx"}→ 说明误用了GenericJackson2JsonRedisSerializer做 key 序列化 - 中文显示成
???或方块 → 编码没指定 UTF-8,或客户端(如 Redis Desktop Manager)本身编码设置不对
检查并强制 StringRedisTemplate 使用 UTF-8
不要依赖自动配置,显式声明 Bean 并绑定编码:
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate(factory);
// 关键:必须显式设置 valueSerializer,否则可能 fallback 到默认 JDK 序列化
template.setValueSerializer(new StringRedisSerializer(StandardCharsets.UTF_8));
template.setHashValueSerializer(new StringRedisSerializer(StandardCharsets.UTF_8));
template.afterPropertiesSet();
return template;
}
注意点:
-
setKeySerializer和setHashKeySerializer不用设 ——StringRedisTemplate构造时已固定为StringRedisSerializer - 必须调用
afterPropertiesSet(),否则部分序列化器不生效 - 如果项目中同时存在
RedisTemplate和StringRedisTemplateBean,确保前者加了@Primary,避免干扰后者
别混用 RedisTemplate 和 StringRedisTemplate 的实例
这两个模板底层共用 RedisConnectionFactory,但序列化逻辑完全独立。一旦你在某处写了:
RedisTemplate<string object> redisTemplate = new RedisTemplate(); redisTemplate.setConnectionFactory(factory); // 忘了 set value serializer → 默认是 JdkSerializationRedisSerializer </string>
然后又在其他地方注入 StringRedisTemplate,看似无关,但如果你的 factory 是单例且被多个模板共享,某些旧版 Spring Data Redis(≤ 2.6.x)在初始化时会因顺序问题让 StringRedisTemplate 间接复用错的序列化上下文。
稳妥做法:
- 所有 Redis 操作统一走一个模板:纯字符串用
StringRedisTemplate,对象存取用自定义RedisTemplate - 禁止在业务代码里 new
RedisTemplate或StringRedisTemplate,全部通过@Autowired注入 - 如果要用 JSON 存对象,别往
StringRedisTemplate里塞objectMapper.writeValueAsString(obj)后再 set —— 这样虽然能读,但失去了类型安全;该换RedisTemplate就换
真正容易被忽略的是:StringRedisTemplate 的 setValueSerializer 在 Bean 初始化后不可变,一旦被某个非标准路径(比如测试类里手动 new + set)篡改过,整个应用生命周期内都会生效。查乱码,优先翻 @Bean 方法和测试类里的 new 行为。











