发布于 

Spring Boot 通用解决 LocalDateTime (反)序列化问题

我们在 JDK8 环境中开发使用 LocalDateTime 的时候经常会遇到以下异常:

序列化异常信息
1
2
3
4
5
6
7
8
org.springframework.http.converter.HttpMessageNotReadableException:

JSON parse error: Cannot deserialize value of type `java.time.LocalDateTime` from String "2020-04-21 11:15:10":

Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException) Text '2020-04-21 11:15:10' could not be parsed at index 10;
nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.time.LocalDateTime` from String "2020-04-21 11:15:10":
Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException) Text '2020-04-21 11:15:10' could not be parsed at index 10
at [Source: (PushbackInputStream); line: 11, column: 16] ...

LocalDateTime 是 JDK8 的新特性,并且 LocalDateTime 默认的时间格式是: yyyy-MM-ddTHH:mm:ss,中间多了一个 T 字。我们正常交互上是没有这种 T 字的,所以会造成前后端交互数据的时候出现异常。

解决方法可参考下面代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
* 解决 LocalDateTime 中间含 T 的问题
*
* @author xiaoxuxuy
* @date 2021/6/9 10:53 上午
*/
@Configuration
public class LocalDateTimeConfiguration {

@Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
private String pattern;

@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return builder -> {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);

// 返回时间数据序列化
builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(formatter));

// 接收时间数据反序列化
builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
};
}
}