【Jackson 填坑日记】“java.time.LocalDateTime not supported by default” 全场景解决方案
作者:@Neoest
时间:2025-07-30
关键词:Jackson, java.time.LocalDateTime, JSR-310, Spring Boot, JSON 序列化
1. 问题现场
昨晚上线新版本的考试系统,一调用「试卷详情接口」就 500:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException:
Java 8 date/time type `java.time.LocalDateTime` not supported by default:
add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling
(through reference chain: com.yunjian.examination.vo.ExamPaperVO["generateTime"])
因为是生产环境,没有办法搞到具体异常截图,回顾了下,错误信息跟上面的一模一样
2. 先定位代码
出问题的 VO 很简单:
@Data
public class ExamPaperVO {
private Long id;
private String title;
private LocalDateTime generateTime; // 这里炸了
}
Controller 直接返回:
@GetMapping("/{id}")
public ExamPaperVO detail(@PathVariable Long id) {
return examPaperService.detail(id); // 内部查询后直接 return
}
3. 为什么会报错?
经过查阅资料得知(文末有链接),Jackson 2.x 默认不带 JSR-310 模块(java.time.*),于是序列化 LocalDateTime 时直接蒙圈。
Spring Boot 2.7+ 已帮你依赖了 jackson-datatype-jsr310,但没有自动注册为模块,需要手动或配置开启。
4. 四种解决方案
| 方案 | 场景 | 侵入性 | 备注 |
|---|---|---|---|
| A. 直接注解 | 仅个别字段 | 最低 | 最常用 |
| B. 全局配置 | 全项目统一 | 低 | 推荐 |
| C. 手动注册模块 | 非 Spring | 中 | 通用 |
| D. 自定义序列化器 | 个性格式 | 高 | 最灵活 |
✅ 方案 A:字段级注解(最快)
@Data
public class ExamPaperVO {
private Long id;
private String title;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@JsonSerialize(using = LocalDateTimeSerializer.class)
private LocalDateTime generateTime;
}
优点:零配置,随改随生效
缺点:每个字段都要写,重复劳动
✅ 方案 B:Spring Boot 全局配置(推荐)
Maven 依赖(Spring Boot 2.7+ 已自带,可跳过)
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
配置类
@Configuration
public class JacksonConfig {
@Bean
public Jackson2ObjectMapperBuilderCustomizer customizer() {
return builder -> {
// 统一格式
builder.serializerByType(LocalDateTime.class,
new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
builder.deserializerByType(LocalDateTime.class,
new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
// 关闭时间戳
builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
};
}
}
优点:一次配置,全项目生效
缺点:Spring Boot 专属
✅ 方案 C:手动注册模块(纯 Jackson)
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule()); // 关键
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
适用于非 Spring 环境(如 Vert.x、Quarkus、普通 JavaSE)。
✅ 方案 D:自定义序列化器(复杂格式)
public class CustomLocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm");
@Override
public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers)
throws IOException {
gen.writeString(value.format(FORMATTER));
}
}
// 使用
@JsonSerialize(using = CustomLocalDateTimeSerializer.class)
private LocalDateTime generateTime;
5. 一键复制版补丁(Spring Boot)
<!-- pom.xml 已自带可省 -->
<!-- application.yml -->
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
serialization:
write-dates-as-timestamps: false
6. 小结
| 场景 | 推荐方案 |
|---|---|
| 只想快速修复单个字段 | 方案 A |
| 新项目/统一风格 | 方案 B |
| 非 Spring 框架 | 方案 C |
| 日期格式极度个性化 | 方案 D |
7. 参考资料
如果本文帮到你,记得点赞收藏!评论区一起交流更多 Jackson 坑位~
1万+

被折叠的 条评论
为什么被折叠?



