@JsonFormat用于Jackson处理JSON的序列化与反序列化,@DateTimeFormat用于Spring MVC解析请求参数;二者职责不同,需按场景正确选用并常配合使用。

在 Java 的 Spring Boot REST 接口中,时间日期字段的序列化与反序列化容易出错——前端传过来的字符串解析失败,或后端返回的时间格式不符合预期。关键在于区分两个注解的职责:@JsonFormat 作用于 JSON 序列化/反序列化(即 Jackson),@DateTimeFormat 作用于 HTTP 请求参数解析(如 @RequestParam、@ModelAttribute)。二者常配合使用,但不可互相替代。
@JsonFormat:控制 JSON 时间格式(响应 + 请求体)
该注解由 Jackson 处理,适用于 @RequestBody 接收的 JSON 对象中的时间字段,以及 返回给前端的 JSON 响应体 中的时间字段。
- 必须搭配
@JsonProperty或直接写在LocalDateTime/Date/Instant字段上 - 常用属性:
pattern(指定格式,如"yyyy-MM-dd HH:mm:ss")、timezone(如"GMT+8",避免时区偏差)、locale(影响月份/星期名称) - 对
Instant类型,建议同时设timezone = "GMT+8",否则可能因默认 UTC 导致显示早 8 小时
示例:
public class OrderDTO {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime createTime;
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private LocalDate orderDate;
}
@DateTimeFormat:处理 URL 查询参数与表单提交
该注解由 Spring MVC 的数据绑定机制处理,仅适用于 @RequestParam、@ModelAttribute 绑定的字符串参数(如 /api/orders?startTime=2024-05-01 09:00:00)。
立即学习“Java免费学习笔记(深入)”;
- 不适用于
@RequestBody中的 JSON 字段(那是 Jackson 的事) - 支持
pattern(推荐)、iso(如 ISO_DATE_TIME)、style(短/中/长格式) - 若未标注且参数是时间类型,Spring 默认只接受 ISO 格式(如
2024-05-01T09:00:00),否则报 400 错误
示例:
@GetMapping("/orders")
public List<Order> listOrders(
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate) {
// ...
}
全局配置建议(减少重复标注)
为避免每个字段都加注解,可统一配置 Jackson 和 Spring MVC 的默认行为:
-
Jackson 全局格式:在
application.yml中配置
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
serialization:
write-dates-as-timestamps: false
⚠️ 注意:该配置对 LocalDateTime 无效(它不是 JDK 传统日期类),仍需 @JsonFormat;但对 Date 和 Instant 生效。
-
Spring MVC 全局日期格式:自定义
WebMvcConfigurer
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
registrar.setDateFormatter(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
registrar.setDateTimeFormatter(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
registrar.setTimeFormatter(DateTimeFormatter.ofPattern("HH:mm:ss"));
registrar.registerFormatters(registry);
}
}
常见坑与验证要点
实际开发中高频出错点:
- 前端传
"2024-05-01 10:30:00"到@RequestBody的LocalDateTime字段 → 必须用@JsonFormat,@DateTimeFormat完全无效 - 用
@RequestParam接收LocalDateTime但没加@DateTimeFormat→ 默认只认2024-05-01T10:30:00,空格格式直接 400 - 返回
Instant未设timezone→ 前端看到的是 UTC 时间(比北京时间晚 8 小时) - MySQL 存储
datetime字段,Java 用LocalDateTime映射 → 确保数据库连接 URL 含serverTimezone=GMT%2B8,否则可能时区错乱
接口调试时,用 Postman 检查请求头 Content-Type: application/json 是否正确,并确认时间字符串是否符合所设 pattern。


















