👋 前言
你是否在返回接口数据时,遇到如下令人抓狂的异常?
***.fasterxml.jackson.databind.exc.InvalidDefinitionException:
Java 8 date/time type `java.time.LocalDateTime` not supported by default:
add Module "***.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling
你是否试过在 @RestController 中返回一个含 LocalDateTime 字段的实体,却发现时间变成了一串数字时间戳,或干脆直接报错?
别急,其实这是 Jackson 在处理 Java 8 时间类型时的“老毛病”——它默认并不支持 LocalDateTime、LocalDate、LocalTime 这些类型的序列化和反序列化。
更麻烦的是,即便你加上了 jackson-datatype-jsr310 模块,如果配置不当,仍然会有坑。
为了解决这些问题,我写了一个 Spring Boot 下的统一配置类 —— ConvertConfiguration。
🧩 这个类是干什么用的?
ConvertConfiguration 是一个实现了 WebMv***onfigurer 接口的配置类,作用可以概括为三点:
1️⃣ 支持 Java 8 时间类型的 JSON 序列化与反序列化
Jackson 默认不支持 LocalDateTime 等类型,我们在此手动注册了 JavaTimeModule 模块,并配上格式化器:
javaTimeModule.addSerializer(LocalDateTime.class, new CustomLocalDateTimeSerializer(DATE_TIME_FORMATTER));
javaTimeModule.addDeserializer(LocalDateTime.class, new CustomLocalDateTimeDeserializer(DATE_TIME_FORMATTER));
格式使用的是常见的:
yyyy-MM-dd HH:mm:ss
所以,不管是响应 JSON,还是接收参数绑定,都可以正常解析。
2️⃣ 解决异常:InvalidDefinitionException
这段异常是不是似曾相识?
***.fasterxml.jackson.databind.exc.InvalidDefinitionException:
Java 8 date/time type `java.time.LocalDateTime` not supported by default:
add Module "***.fasterxml.jackson.datatype:jackson-datatype-jsr310"
是的,这个类通过 registerModule(new JavaTimeModule()) 手动解决了 Jackson 不支持 Java 时间类型的问题。
你不再需要为每个时间字段单独加 @JsonFormat,也不用在控制器手动处理时间转换。
3️⃣ 自动处理时区转换(默认支持 Asia/Shanghai)
国内开发者最熟悉的痛点:Java 的时间默认是 UTC,但我们实际想用的是北京时间(Asia/Shanghai)。如果你不特别指定时区,很多时候:
-
数据库存的是东八区时间;
-
但前端拿到的是 UTC;
-
甚至部分序列化成字符串时被“悄悄减了8小时”。
这个类通过以下配置避免了这一坑:
objectMapper.setTimeZone(TimeZone.getTimeZone(ZoneId.of("Asia/Shanghai")));
<