为什么需要自定义Jackson序列化和反序列化?下面举个例子看看就知道了
问题描述
由于 Spring Boot 内置使用的就是 Jackson
JSON 框架,所以,无需引入新的依赖,仅需添加自定义配置类即可,让其支持新的日期 API
Controller层的代码如下
java
@RestController
public class TestController {
@PostMapping("/test2")
public Response<User> test2(@RequestBody User user) {
return Response.success(user);
}
}
定义一个实体类User但是实体类含有LocalDateTime的日期类型
public class User {
/**
* 昵称
*/
private String nickName;
/**
* 创建时间
*/
private LocalDateTime createTime;
}
可以通过Postman这些工具来测试一下
下面是入参
{
"nickName" : "小明",
"createTime": "2024-05-14 12:00:00"
}
你回发现一个问题就是,会报错
JSON parse error: Cannot deserialize value of type `java.time.LocalDateTime` from String "2024-05-14 12:00:00": Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException) Text '2024-05-14 12:00:00' could not be parsed at index 10]
提示我们 JSON 解析错误,无法将
2024-05-14 12:00:00
字符串解析为java.time.LocalDateTime
日期类。
问题解决
需要自己定义一个配置类,覆盖框架本身的配置
java
@Configuration
public class JacksonConfig {
@Bean
public ObjectMapper objectMapper() {
// 初始化一个 ObjectMapper 对象,用于自定义 Jackson 的行为
ObjectMapper objectMapper = new ObjectMapper();
// 忽略未知属性
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
// 设置时区
objectMapper.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
// JavaTimeModule 用于指定序列化和反序列化规则
JavaTimeModule javaTimeModule = new JavaTimeModule();
// 支持 LocalDateTime、LocalDate、LocalTime
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
// 支持 YearMonth
javaTimeModule.addSerializer(YearMonth.class, new YearMonthSerializer(DateTimeFormatter.ofPattern("yyyy-MM")));
javaTimeModule.addDeserializer(YearMonth.class, new YearMonthDeserializer(DateTimeFormatter.ofPattern("yyyy-MM")));
objectMapper.registerModule(javaTimeModule);
return objectMapper;
}
}
完成之后,出入参实体类中就能支持定义 LocalDateTime 日期 API 了