spring boot统一json序列化和时区转换的核心是定制objectmapper:一、yml配置time-zone和date-format(仅对date生效)并禁用fail-on-unknown-properties;二、代码注册objectmapper,注册javatimemodule、禁用write_dates_as_timestamps,并为localdatetime等配置序列化/反序列化器;三、@jsonformat用于字段级格式微调;四、需同步配置mysql连接时区、jvm时区及前端解析逻辑以保障全链路一致。

Spring Boot 中统一处理 JSON 序列化和时区转换,核心是围绕 Jackson 的 ObjectMapper 做定制化配置。默认行为常导致时间格式混乱(如 ISO 8601 带 T 和 Z)、时区错位(如后端显示比前端预期快/慢 8 小时)、LocalDateTime 变数组、多余字段直接报错等问题。解决的关键不是零散加注解,而是建立一套可复用、可维护的全局规则。
一、application.yml 全局基础配置
这是最轻量、最常用的起点,适合中小项目或快速对齐基本格式:
-
指定默认时区:确保序列化输出的时间字符串按目标时区(如东八区)展示
spring.jackson.time-zone=GMT+8 或更推荐 spring.jackson.time-zone=Asia/Shanghai -
统一日期格式:影响
Date、Calendar等老式类型(注意:对LocalDateTime无效)
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss -
提升容错性:避免前端多传字段导致接口 400 报错
spring.jackson.deserialization.fail-on-unknown-properties=false -
忽略空值字段:减少冗余 JSON 字段,提升传输效率
spring.jackson.default-property-inclusion=NON_NULL
二、自定义 ObjectMapper 替换默认 Bean
application.yml 对 Java 8 时间类型(LocalDateTime、LocalDate)支持有限,必须通过代码注册定制的 ObjectMapper。Spring Boot 会自动识别并使用它:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 新建配置类,用
@Bean注册返回ObjectMapper实例 - 创建
SimpleModule,为LocalDateTime、LocalDate、LocalTime分别注册自定义的JsonSerializer和JsonDeserializer - 设置序列化器使用
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"),反序列化器也匹配同一格式 - 调用
disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)防止时间被转成毫秒数 - 启用
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES = false(与 yml 配置效果一致,但代码级更可控)
三、@JsonFormat 注解用于局部微调
当某个字段需要和其他字段不同格式(如订单创建时间用精确到秒,日志时间要带毫秒),或实体来自三方库无法修改全局配置时,可用注解精准控制:
- 加在字段上:
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS", timezone = "GMT+8") -
timezone参数仅对Date类型生效;对LocalDateTime,时区由全局spring.jackson.time-zone或序列化器内部逻辑决定,此处设了也忽略 - 注意:该注解只影响 JSON 序列化/反序列化,不影响数据库存取或业务逻辑中的时区计算
四、时区一致性必须前后端对齐
光配 Spring Boot 不够,时区问题本质是“存储—传输—展示”链路不一致:
- MySQL 连接 URL 中加上
serverTimezone=Asia/Shanghai,否则 JDBC 驱动可能把时间按 UTC 解析 - 确认 MySQL 服务端时区:执行
SELECT @@global.time_zone, @@session.time_zone;,建议设为+08:00而非CST(易歧义) - Java 应用启动时 JVM 时区最好也显式指定:
-Duser.timezone=Asia/Shanghai,避免依赖操作系统默认值 - 前端接收时间字符串后,建议统一用
new Date(str)解析(现代浏览器会按本地时区自动适配),而非手动加减小时










