Spring Boot Jackson 日期序列化差 8 小时问题与解决方案

发表于 2025-09-19 18:17:13 分类于 默认分类 阅读量 61

Spring Boot Jackson 日期序列化差 8 小时问题与解决方案

在 Spring Boot 项目中,很多同学遇到过这样的问题: 数据库里存的时间是正确的,但接口返回的 JSON 时间却少了 8 小时

这个问题通常出在 Jackson 的时区配置。本文带你彻底解决。


🔍 问题现象

  1. MySQL 数据库存的是:
2025-09-19 17:56:59
  1. 接口返回的 JSON 却是:
2025-09-19 09:56:59

差了整整 8 个小时。 即使 MySQL、JDBC 配置了 serverTimezone=Asia/Shanghai,还是会遇到这种情况。

原因就是:Jackson 默认使用 JVM 的时区,如果 JVM 没设置 -Duser.timezone,很可能走了 UTC


✅ 解决方案

1. 在 application.yml 中配置 Jackson

spring:
  jackson:
    # 控制 JSON 返回时 null 字段处理策略
    default-property-inclusion: always

    # 日期类型格式化
    date-format: yyyy-MM-dd HH:mm:ss

    # 设置时区,避免默认使用 UTC
    time-zone: Asia/Shanghai
  • date-format → 控制 DateTimestamp 的序列化格式
  • time-zone → 控制 Jackson 输出时间的时区(关键参数!)

这样设置后,接口返回的时间就能和数据库保持一致。


2. 针对 Java 8 时间 API (LocalDateTime 等)

如果你的实体字段是 LocalDateTimeLocalDate 等,默认不会走 date-format,需要额外处理:

方法 A:使用注解

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
private LocalDateTime createTime;

方法 B:统一配置 jackson-datatype-jsr310

Spring Boot 默认已集成,只需要全局配置即可(同样支持 time-zone)。


3. JVM 启动参数兜底

如果你的服务跑在容器或服务器上,可以加 JVM 参数,确保默认时区一致:

-Duser.timezone=Asia/Shanghai

这样 Jackson、JVM、数据库、JDBC 就能保持统一。


📌 总结

  • 数据库时区:设置为 +08:00Asia/Shanghai
  • JDBC URL:加 serverTimezone=Asia/Shanghai
  • Jackson 配置:加 date-format + time-zone
  • 实体类时间类型:推荐用 LocalDateTime,并配合 @JsonFormat

只要三层时区保持一致,就能彻底避免 时间差 8 小时 的坑。 🚀