背景
-
不知道大家在工作和学习中有没有遇到过,新起一个SpringBoot项目,操作增删改查业务且入参和出参中含有LocalDateTime的序列化与反序列化问题。如在接收时间类型的参数时,报错: Failed to convert from type [java.lang.String] to type [java.time.LocalDateTime] for value '2020-12-12 00:00:00'; 而在返回给前端小朋友的LocalDateTime格式是数组格式的,让前端抓耳挠腮。 这些都是由于LocalDateTime没有合理的序列化和反序列化引起的问题。
-
序列化:把Java对象转换为字节序列的过程。
-
反序列化:把字节序列恢复为Java对象的过程。
解决方案
- 以k-v样式拼接在url的LocalDateTime参数反序列化(局部):加在参数字段上哦
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
- url参数反序列化(全局):
@ControllerAdvice
public class ExceptionResolver {
@InitBinder
public void initBinder(WebDataBinder webDataBinder) {
webDataBinder.registerCustomEditor(LocalDate.class, new PropertyEditorSupport() {
@Override
public void setAsText(String text) throws IllegalArgumentException {
setValue(LocalDate.parse(text, DateTimeFormatter.ISO_DATE));
}
});
webDataBinder.registerCustomEditor(LocalDateTime.class, new PropertyEditorSupport() {
@Override
public void setAsText(String text) throws IllegalArgumentException {
setValue(LocalDateTime.parse(text, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
}
});
webDataBinder.registerCustomEditor(LocalTime.class, new PropertyEditorSupport() {
@Override
public void setAsText(String text) throws IllegalArgumentException {
setValue(LocalTime.parse(text, DateTimeFormatter.ISO_TIME));
}
});
}
}
- body里的json格式入参(局部解决):加在参数字段上哦
@JsonFormat(shape = JsonFormat.Shape.STRING,pattern = "yyyy-MM-dd HH:mm:ss")
- body里json格式入参(全局解决):其中的序列化代码解决了出参格式化问题哦。代码放在@Confuguration开头的类中
@Bean(name = "mapperObject")
public ObjectMapper getObjectMapper() {
ObjectMapper om = new ObjectMapper();
JavaTimeModule javaTimeModule = new JavaTimeModule();
//序列化,写入输出流
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
//反序列,读取输入流,只能反序列化放到Body里的json格式数据哦
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
om.registerModule(javaTimeModule);
return om;
}