[Java]RedisTemplate自定义序列化配置

53 阅读1分钟

在 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);
    }
}