SpringBoot中LocalDateTime序列化与反序列化解决方案

2,883 阅读1分钟

背景

  • 不知道大家在工作和学习中有没有遇到过,新起一个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;
    }