redistemplate默认使用jdkserializationredisserializer序列化value,导致数据不可读、体积大、跨语言不兼容且反序列化易失败;推荐改用jackson2jsonredisserializer并配置objectmapper启用defaulttyping和javatimemodule,同时需显式设置hashkey/hashvalue序列化器,或选用stringredistemplate手动json编解码。

RedisTemplate 默认用 JdkSerializationRedisSerializer 序列化 value,存进去是一串不可读的二进制,反序列化还容易报 ClassNotFoundException 或 InvalidClassException。想存 User、Order 这类对象,必须换掉默认序列化器。
为什么不能直接用默认的 JdkSerializationRedisSerializer
它要求所有对象实现 Serializable,且类名、字段、serialVersionUID 一改就反序列化失败;序列化后体积大、不可读、跨语言完全不兼容。比如存一个简单 User 对象,Redis CLI 里看到的是类似 aced000573720019636f6d2e6578616d706c652e55736572... 的乱码。
GenericJackson2JsonRedisSerializer 是最稳妥的入门选择
它把对象转成 JSON 字符串再存,人类可读、跨语言友好、字段增删基本不影响反序列化(只要不删必需字段)。但要注意三点:
-
GenericJackson2JsonRedisSerializer已被标记为@Deprecated(Spring Data Redis 3.2+),应改用Jackson2JsonRedisSerializer - 必须配置
ObjectMapper启用DefaultTyping.NON_FINAL,否则反序列化时无法还原具体类型,会变成LinkedHashMap - 时间类型(
LocalDateTime等)需手动注册JavaTimeModule,否则抛JsonMappingException
示例关键代码:
@Bean
public RedisTemplate<string object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<string object> template = new RedisTemplate();
template.setConnectionFactory(factory);
StringRedisSerializer stringSerializer = new StringRedisSerializer();
template.setKeySerializer(stringSerializer);
template.setHashKeySerializer(stringSerializer);
Jackson2JsonRedisSerializer<object> jsonSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
om.registerModule(new JavaTimeModule());
jsonSerializer.setObjectMapper(om);
template.setValueSerializer(jsonSerializer);
template.setHashValueSerializer(jsonSerializer);
template.afterPropertiesSet();
return template;
}</object></string></string>
哈希结构(HASH)要单独配 hashKey 和 hashValue 序列化器
redisTemplate.opsForHash().put("user:1001", "profile", profileObj) 这种操作,key 是字符串(如 "profile"),value 是对象(如 Profile)。如果只设了 setValueSerializer,hashValue 仍走默认 JDK 序列化——结果就是哈希表里 value 又变乱码。
- 必须显式调用
template.setHashKeySerializer(...)和template.setHashValueSerializer(...) - 推荐统一用
StringRedisSerializer处理 hash key(毕竟一般用字符串作 field 名),用 JSON 序列化器处理 hash value - 别漏掉
template.afterPropertiesSet(),否则配置不生效
生产环境建议用 StringRedisTemplate + 手动 JSON 转换
如果你只存业务对象、不依赖 RedisTemplate 的泛型操作,StringRedisTemplate 更轻量、更可控:
- 它默认所有 key/value 都是
String,天然避免序列化陷阱 - 用
ObjectMapper.writeValueAsString(obj)存,ObjectMapper.readValue(str, User.class)取,逻辑清晰、调试方便 - 能精确控制每个字段的序列化行为(比如忽略 null、格式化日期),而不用全局配置
ObjectMapper
真正难的不是选哪种序列化器,而是保证反序列化时 classpath 里有对应类、且版本兼容——JSON 至少让你一眼看出存的是什么,出问题时不用猜字节流里藏了啥。











