【问题标题】:Spring Boot LocalDate field serialization and deserializationSpring Boot LocalDate 字段序列化和反序列化
【发布时间】:2015-09-01 11:43:28
【问题描述】:

在 Spring Boot 1.2.3.RELEASE 中使用 fasterxml 将LocalDate 字段序列化和反序列化为 ISO 日期格式字符串的正确方法是什么?

我试过了:

  • spring.jackson.serialization.write-dates-as-timestamps:false 在 application.properties 文件中,

  • 在项目中包含jackson-datatype-jsr310,然后使用

    • @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")注解

    • @DateTimeFormat(iso=ISO.DATE)注解,

  • Jsr310DateTimeFormatAnnotationFormatterFactory 添加为格式化程序:

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addFormatterForFieldAnnotation(new Jsr310DateTimeFormatAnnotationFormatterFactory());
    }
    

以上都没有帮助。

【问题讨论】:

    标签: json date serialization spring-boot spring-data-rest


    【解决方案1】:
    compile ("com.fasterxml.jackson.datatype:jackson-datatype-jsr310")
    

    在 build.gradle 中 然后以下注释有所帮助:

    @JsonDeserialize(using = LocalDateDeserializer.class)
    @JsonSerialize(using = LocalDateSerializer.class)
    private LocalDate birthday;
    

    更新:如果您使用的是 Spring Boot 2.*,则依赖项已通过“启动器”之一包含在内。

    【讨论】:

    • 这为我解决了问题。升级使用spring boot 1.3.0.BUILD.SNAPSHOT版本时遇到反序列化问题。
    • 你能指定你的解决方案吗?
    • 是的,您需要 com.fasterxml.jackson.datatype:jackson-datatype-jsr310 依赖项,然后您可以将 @JsonDeserialize @JsonSerialize 注释与 LocalDate 字段一起使用,就像答案中一样。
    • 在 SpringBoot 1.3.6.RELEASE 上对我不起作用;/ 出现错误:com.fasterxml.jackson.datatype.jsr310.ser.JSR310FormattedSerializerBase.findFormatOverrides(Lcom/fasterxml/jackson/databind/SerializerProvider;Lcom/fasterxml/jackson/databind/BeanProperty;Ljava/lang/Class;)Lcom/fasterxml/jackson/annotation/JsonFormat$Value;
    • 解决了我的问题。使用 LocalDateTime 杰克逊反序列化,谢谢
    【解决方案2】:

    在我的 Spring Boot 2 应用程序中

    • @JsonFormat 注解在(反)序列化 JSON 数据时在 REST 控制器中使用。
    • @DateTimeFormat 注解在其他控制器中使用 ModelAttributes 在(反)序列化字符串数据时。

    您可以在同一个字段上指定两者(如果您在 JSON 和 Thymeleaf 模板之间共享 DTO,这很有用):

    @JsonFormat(pattern = "dd/MM/yyyy") 
    @DateTimeFormat(pattern = "dd/MM/yyyy")
    private LocalDate birthdate;
    

    Gradle 依赖:

    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-json'
    

    我希望这是您在 Spring Boot 2.x 应用程序中自定义日期/时间格式所需的所有配置。


    对于 Spring Boot 1.x 应用,指定额外的注解和依赖:

    @JsonFormat(pattern = "dd/MM/yyyy")
    @DateTimeFormat(pattern = "dd/MM/yyyy")
    @JsonDeserialize(using = LocalDateDeserializer.class)
    @JsonSerialize(using = LocalDateSerializer.class)
    private LocalDate birthDate;
    
    // or
    @JsonFormat(pattern = "dd/MM/yyyy HH:mm")
    @DateTimeFormat(pattern = "dd/MM/yyyy HH:mm")
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    @JsonSerialize(using = LocalDateTimeSerializer.class)
    private LocalDateTime birthDateTime;
    
    implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.9.8'
    

    请注意,如果有人以错误的格式发送日期,您的 API 将抛出“JSON 解析错误”。映射示例:

    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate releaseDate;
    

    异常示例:

    HttpMessageNotReadableException:JSON 解析错误:无法从字符串“2002”反序列化 java.time.LocalDate 类型的值:无法反序列化 java.time.LocalDate:(java.time.format.DateTimeParseException)无法在索引 4 处解析文本“2002”;嵌套异常是com.fasterxml.jackson.databind.exc.InvalidFormatException:无法从字符串“2002”反序列化java.time.LocalDate 类型的值:无法反序列化java.time.LocalDate:(java.time.format.DateTimeParseException)无法在索引4 处解析文本“2002”

    【讨论】:

      【解决方案3】:

      如果您想使用自定义 Java 日期格式化程序,请添加 @JsonFormat 注释。

      @JsonFormat(pattern = "dd/MM/yyyy")
      @JsonDeserialize(using = LocalDateDeserializer.class)
      @JsonSerialize(using = LocalDateSerializer.class)
      private LocalDate birthdate;*
      

      【讨论】:

        【解决方案4】:

        其实只要在 pom.xml 中指定依赖就可以了。

        这样,我所有的 LocalDate 字段都会自动使用 ISO 格式,无需注释:

        <!-- This is enough for LocalDate to be deserialized using ISO format -->
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
        </dependency>
        

        在 Spring Boot 1.5.7 上测试。

        【讨论】:

          【解决方案5】:
           @Bean
          public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
              return builder -> {
                  DateTimeFormatter localDateFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
                  builder.serializerByType(LocalDate.class, new LocalDateSerializer(localDateFormatter));
                  builder.deserializerByType(LocalDate.class, new LocalDateDeserializer(localDateFormatter));
          
                  DateTimeFormatter localDateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
                  builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(localDateTimeFormatter));
                  builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(localDateTimeFormatter));
              };
          }
          

          【讨论】:

            猜你喜欢
            • 2019-04-03
            • 2018-09-29
            • 1970-01-01
            • 2020-01-09
            • 2021-05-18
            • 1970-01-01
            • 2017-10-30
            • 2017-05-24
            • 2018-02-05
            相关资源
            最近更新 更多