kd_687318643 2026-02-14 21:14 采纳率: 100%
浏览 2
已采纳

Spring Boot 集成 Redis 存储数据遇 LocalDateTime 序列化难题,求破!

我搞 Spring Boot 项目集成 Redis 当缓存,配置好相关依赖和连接信息后,准备往 Redis 存数据,结果报了序列化异常。我用的 RedisTemplate,配置了用 Jackson2JsonRedisSerializer 来处理 value 的序列化。要存的数据对象里有个 LocalDateTime 类型的字段,像创建时间这种。异常信息提示说不是 JSON 对象,是 LocalDateTime 类型导致的序列化问题。我试过在 ObjectMapper 里加日期格式化配置,也换过序列化方式,用 GenericJackson2JsonRedisSerializer 也不行。我就纳闷了,为啥常规配置处理不了 LocalDateTime 类型呢?有没有啥办法能解决,让我顺利把带这个类型的数据存进 Redis 呀?还有,用 Redis 缓存时,日期时间类型序列化反序列化有啥好办法不?求们指点!

  • 写回答

2条回答 默认 最新

  • 檀越@新空间 2026-02-14 21:15
    关注

    晚上好🌙🌙🌙
    本答案参考通义千问

    在 Spring Boot 项目中使用 Redis 缓存时,如果数据对象中包含 LocalDateTime 类型的字段,确实会遇到 序列化与反序列化异常 的问题。这是因为默认的 JSON 序列化器(如 Jackson)无法直接处理 LocalDateTime 类型,除非你进行额外的配置。


    ✅ 问题分析

    1. 为什么会出现序列化异常?

    Spring Boot 默认使用 Jackson2JsonRedisSerializer 来处理 Redis 中的值序列化,而 Jackson 对 LocalDateTime 的处理需要额外的配置。如果没有正确设置日期格式或类型支持,就会抛出类似以下的异常:

    com.fasterxml.jackson.databind.JsonMappingException: 
    Cannot construct instance of `java.time.LocalDateTime` from String value
    

    2. 为什么不能用 GenericJackson2JsonRedisSerializer?

    虽然 GenericJackson2JsonRedisSerializer 是一个更通用的序列化方式,但它本质上也是基于 Jackson 的,仍然需要对 LocalDateTime 进行正确的格式化配置。


    🔧 解决方案:正确配置 Jackson 处理 LocalDateTime

    步骤一:添加依赖(确保已引入)

    如果你还没引入 Jackson 的依赖,请确保你的 pom.xmlbuild.gradle 中有如下依赖:

    Maven:

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatypes-jsr310</artifactId>
    </dependency>
    

    Gradle:

    implementation 'com.fasterxml.jackson.core:jackson-databind'
    implementation 'com.fasterxml.jackson.datatype:jackson-datatypes-jsr310'
    

    步骤二:自定义 ObjectMapper 配置

    你需要为 ObjectMapper 添加对 LocalDateTime 的支持,并设置日期格式。

    示例代码:

    import com.fasterxml.jackson.annotation.JsonFormat;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
    
    @Configuration
    public class RedisConfig {
    
        @Bean
        public GenericJackson2JsonRedisSerializer redisSerializer() {
            ObjectMapper mapper = new ObjectMapper();
            // 注册 JavaTimeModule 模块
            mapper.registerModule(new JavaTimeModule());
            // 设置日期格式
            mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
            return new GenericJackson2JsonRedisSerializer(mapper);
        }
    }
    

    步骤三:配置 RedisTemplate 使用自定义序列化器

    确保你的 RedisTemplate 使用了这个自定义的序列化器。

    示例配置类:

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    
    @Configuration
    public class RedisTemplateConfig {
    
        @Bean
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
            RedisTemplate<String, Object> template = new RedisTemplate<>();
            template.setConnectionFactory(factory);
    
            // key 使用 String 序列化
            template.setKeySerializer(new StringRedisSerializer());
            template.setHashKeySerializer(new StringRedisSerializer());
    
            // value 使用自定义的 GenericJackson2JsonRedisSerializer
            template.setValueSerializer(redisSerializer());
            template.setHashValueSerializer(redisSerializer());
    
            return template;
        }
    
        @Bean
        public GenericJackson2JsonRedisSerializer redisSerializer() {
            ObjectMapper mapper = new ObjectMapper();
            mapper.registerModule(new JavaTimeModule());
            mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
            return new GenericJackson2JsonRedisSerializer(mapper);
        }
    }
    

    ✅ 常见注意事项

    | 事项 | 说明 | |------|------| | 日期格式一致性 | 存储和读取时要保持一致,例如 yyyy-MM-dd HH:mm:ss | | JavaTimeModule 注册 | 必须注册该模块才能支持 LocalDateTime 等 JSR-310 类型 | | 避免使用 JDK 8 之前的 Date 类型 | 如果可能,尽量使用 LocalDateTime 而不是 Date | | 可选:使用@JsonFormat注解 | 在实体类中加 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") 更灵活 |


    🧠 补充建议:推荐使用 String 存储时间

    如果你只是存储时间信息,可以考虑将 LocalDateTime 转换为字符串(如 ISO 格式 2025-04-05T12:34:56),这样可以避免复杂的序列化配置。

    示例转换方法:

    String dateTimeStr = LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME);
    

    ✅ 总结

    解决 Spring Boot + Redis 存储 LocalDateTime 序列化问题的关键步骤是:

    1. 添加 Jackson 的 JavaTimeModule 依赖
    2. 自定义 ObjectMapper 并注册 JavaTimeModule
    3. 设置日期格式(如 yyyy-MM-dd HH:mm:ss
    4. 配置 RedisTemplate 使用自定义的 GenericJackson2JsonRedisSerializer

    如果你还有其他关于 Redis 缓存、数据类型、序列化的问题,欢迎继续提问!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 已采纳回答 2月14日
  • 创建了问题 2月14日