优雅解决 SpringBoot 在 JDK8 中 LocalDateTime (反)序列化问题

在做项目的时候很容易遇到这种问题:

org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type java.time.LocalDateTime from String \"2020-02-15 22:13:15\": Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException) Text '2020-02-15 22:13:15' 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-02-15 22:13:15\": Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException) Text '2020-02-15 22:13:15' could not be parsed at index 10\n at [Source: (PushbackInputStream); line: 1, column: 15]

出现这种问题的原因是项目中使用了 JDK8 中全新的日期和时间类:LocalDateTime。LocalDateTime 默认的时间格式是: yyyy-MM-ddTHH:mm:ss,中间多了一个 T 字,但是对于往常的数据来说是没有 T 字的,这就会造成后端在接受或返回时间数据的时候出现异常,解决方案如下(添加一个配置类,千万不要忘了 @Configuration 注解):

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;

/**
 * @author roc
 */
@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));
        };
    }

}

【注】服务器接收前端的时间数据并处理是反序列化:将流数据转换成 LocalDateTime,服务器返回给前端数据是序列化:将 LocalDateTime 数据转换成流;两个一般成对出现,也可以只用其中的某一个。

2 条评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注