问题引入 今天在做项目时前端传过来的json对象给后端时后台出现如下报错信息:
Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type java.time.LocalDateTime
from String “2020-11-06 22:48:18”: Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException) Text ‘2020-11-06 22:48:18’ 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-11-06 22:48:18”: Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException) Text ‘2020-11-06 22:48:18’ could not be parsed at index 10
报错信息主要是说 在将字符串’2020-11-06 22:48:18’反序列化成LocalDateTime对象时发生了异常。
原因 默认情况下jackson 只能将”2020-11-06T
22:48:18”转成LocalDateTime对象,可是”2018-09-20T
08:01:00”这种格式的时间不符合国人的习惯,所以我之前将返回给前端的时间格式改成了”2020-11-06 22:48:18”,即默认时间格式中的T
被换成了空格
。
问题也就随之而来了,报错信息显示在反序列化时间字符串时,字符串索引位置10处(即原来的T
被换成了空格
,导致默认的LocalDateTime反序列化器解析时间字符串失败)无法被解析。
默认的LocalDateTime序列化器只能将默认的时间格式”2020-11-06T
22:48:18”转成LocalDateTime,而被我们改过格式的”2020-11-06 22:48:18”是不能被默认的LocalDateTime反序列化器转成LocalDateTime的。
也就是说 我们修改了默认的LocalDateTime序列化器 输出的时间格式,但却并没有同时修改与其对应的反序列化器 ,所以我们只需要再添加一个能够解析我们自定义的时间格式的LocalDateTime反序列化器
即可。
解决办法 先看我们之前的代码 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 36 37 38 39 40 41 42 43 44 45 46 @Configuration public class LocalDateTimeConverter implements Converter <String , LocalDateTime > { @Value("${spring.mvc.format.date}") private String format; @Override public LocalDateTime convert (String s) { DateTimeFormatter df = DateTimeFormatter.ofPattern(format); LocalDateTime date = null ; try { date = LocalDateTime.parse(s, df); } catch (Exception e) { e.printStackTrace(); } return date; } @Bean public LocalDateTimeSerializer localDateTimeSerializer () { return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(format)); } @Bean public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer () { return builder -> builder.serializerByType(LocalDateTime.class, localDateTimeSerializer()); } }
修改后的代码: 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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 @Configuration public class LocalDateTimeConverter implements Converter <String , LocalDateTime > { @Value("${spring.mvc.format.date}") private String format; @Override public LocalDateTime convert (String s) { DateTimeFormatter df = DateTimeFormatter.ofPattern(format); LocalDateTime date = null ; try { date = LocalDateTime.parse(s, df); } catch (Exception e) { e.printStackTrace(); } return date; } @Bean public LocalDateTimeSerializer localDateTimeSerializer () { return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(format)); } @Bean public LocalDateTimeDeserializer localDateTimeDeserializer () { return new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(format)); } @Bean public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer () { return builder -> builder .serializerByType(LocalDateTime.class, localDateTimeSerializer()) .deserializerByType(LocalDateTime.class,localDateTimeDeserializer()); } }