必须注册JavaTimeModule模块才能使@JsonFormat生效,否则抛InvalidDefinitionException;需配置WRITE_DATES_AS_TIMESTAMPS=false并确保jackson-datatype-jsr310依赖存在。

Java 中用 Jackson 序列化 java.time 新日期类(如 LocalDateTime、LocalDate、ZonedDateTime)时,不能直接加 @JsonFormat 就生效——必须先启用对 Java 8 时间类型的模块支持,否则会报 InvalidDefinitionException: Java8 date/time type ... not supported by default。
必须注册 JavaTimeModule
这是最关键的一步。Jackson 2.6+ 起提供了 JavaTimeModule(对应依赖 jackson-datatype-jsr310),用于支持 java.time.* 类型:
- Spring Boot 项目:通常自动注册,无需手动操作(2.2+ 版本默认启用)
- 纯 Jackson 或老 Spring Boot:需显式注册模块
手动注册示例:
ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JavaTimeModule()); // 或更推荐:自动扫描 classpath 下所有模块 mapper.findAndRegisterModules();
@JsonFormat 注解要搭配 pattern 和 timezone(可选)
注解本身只起“格式提示”作用,真正生效依赖模块注册 + 字段类型匹配:
-
LocalDateTime:pattern 必须不含时区信息,例如"yyyy-MM-dd HH:mm:ss" -
LocalDate:用"yyyy-MM-dd";LocalTime:用"HH:mm:ss" -
ZonedDateTime或OffsetDateTime:建议加上timezone = "GMT+8"或使用WRITE_DATES_WITH_ZONE_ID = false控制输出格式
字段示例:
public class Order {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime createTime;
<pre class="brush:php;toolbar:false;">@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate orderDate;
}
全局配置关闭时间戳输出
即使加了 @JsonFormat,若没关掉默认时间戳行为,仍可能输出数字(如 1734532800000):
ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JavaTimeModule()); mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
这个配置让所有日期类型(包括 Date 和 java.time)都走字符串格式化逻辑,而非毫秒值。
Maven 依赖确认
确保项目含以下依赖(Spring Boot 2.3+ 已内置,但显式声明更稳妥):
<dependency><groupid>com.fasterxml.jackson.datatype</groupid><artifactid>jackson-datatype-jsr310</artifactid><version>2.15.2</version><!-- 建议用当前最新稳定版 --></dependency>
注意:jsr310 是必须的;jackson-datatype-jdk8(支持 Optional 等)按需添加。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











