在 Spring 的 RedisTemplate 中自定义序列化配置,其中 GenericJackson2JsonRedisSerializer 自定义 ObjectMapper,使其:正确序列化/反序列化 LocalDateTime 等 Java 8 时间类型;忽略 JSON 中未知字段(避免反序列化失败);
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
// key序列化器:使用字符串
StringRedisSerializer keySerializer = new StringRedisSerializer();
// value序列化器:使用json
GenericJackson2JsonRedisSerializer valueSerializer = getGenericJackson2JsonRedisSerializer();
// 设置 key 和 value 的序列化方式
template.setKeySerializer(keySerializer);
template.setValueSerializer(valueSerializer);
template.setHashKeySerializer(keySerializer);
template.setHashValueSerializer(valueSerializer);
template.afterPropertiesSet();
return template;
}
private GenericJackson2JsonRedisSerializer getGenericJackson2JsonRedisSerializer() {
// 配置自定义 ObjectMapper
ObjectMapper objectMapper = new ObjectMapper();
// 1. 注册 JavaTimeModule 以支持 LocalDateTime、LocalDate、LocalTime等时间类型的序列化
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
objectMapper.registerModule(javaTimeModule);
// 2. 禁用将日期写为时间戳(可选,根据需求)
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
// 3. 忽略未知字段(反序列化时遇到 JSON 中有类中没有的字段不报错)
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// 4. 允许字段可见性(确保 private 字段也能序列化)
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 5. 启用类型信息(用于 GenericJackson2JsonRedisSerializer 支持多态)
// 使用 BasicPolymorphicTypeValidator 替代已废弃的 DefaultTyping
objectMapper.activateDefaultTyping(
BasicPolymorphicTypeValidator.builder()
.allowIfBaseType(Object.class) // 或更严格的限制
.build(),
ObjectMapper.DefaultTyping.NON_FINAL,
JsonTypeInfo.As.PROPERTY
);
// 创建序列化器
return new GenericJackson2JsonRedisSerializer(objectMapper);
}
}