背景
新起一个SpringBoot项目,操作增删改查业务且入参和出参中含有LocalDateTime、LocalDate、LocalTime的序列化与反序列化问题。如在接收时间类型的参数时,报错: 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参数反序列化
局部解决方案
加在参数字段上
@GetMapping("/test")
public CommonResult test(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @RequestParam(required = false) LocalDateTime time) {
System.out.println(time);
return CommonResult.success(time);
}
全局解决方案
@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")
@TableField("create_time")
private LocalDateTime createTime;
@JsonFormat(shape = JsonFormat.Shape.STRING,pattern = "yyyy-MM-dd HH:mm:ss")
@TableField("update_time")
private LocalDateTime updateTime;
全局解决方案
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;
}