【问题标题】:Can not deserialize value of type java.time.LocalDateTime from String无法从 String 反序列化 java.time.LocalDateTime 类型的值
【发布时间】:2017-09-06 21:33:48
【问题描述】:

我有以下配置:

    @Bean
    @Primary
    public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
//        objectMapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false);
        return objectMapper;
    }

以及以下依赖项:

ext {
        springBootVersion = '1.5.2.RELEASE'
    }
.... 
dependencies {
    compile('org.springframework.boot:spring-boot-starter-websocket')
    compile("org.springframework:spring-messaging")
    compile('org.springframework.boot:spring-boot-starter-actuator')
    compile('org.springframework.boot:spring-boot-starter-thymeleaf')
    compile('org.springframework.boot:spring-boot-starter-validation')
    compile('org.springframework.boot:spring-boot-starter-web')
    compile group: 'net.jcip', name: 'jcip-annotations', version: '1.0'
    compile ("com.fasterxml.jackson.datatype:jackson-datatype-jsr310")
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

我添加了以下控制器:

@PostMapping("/validation_test")
    public String testValidation(@Valid @RequestBody ClientInputMessage clientInputMessage, BindingResult result) {
        logger.info(Arrays.toString(result.getAllErrors().toArray()));
        return "main";
    }


public class ClientInputMessage {
    @NotEmpty
    private String num1;
    @NotEmpty
    private String num2;
    @Past
    private LocalDateTime date;

如果我这样传递 json:

{
      "num1":"324",
      "num2":123,
      "date":"2014-01-01"
    }

应用程序打印以下输出:

Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Can not deserialize value of type java.time.LocalDateTime from String "2014-01-01": Text '2014-01-01' could not be parsed at index 10
 at [Source: java.io.PushbackInputStream@1204f40f; line: 4, column: 8] (through reference chain: model.ClientInputMessage["date"]); nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not deserialize value of type java.time.LocalDateTime from String "2014-01-01": Text '2014-01-01' could not be parsed at index 10
 at [Source: java.io.PushbackInputStream@1204f40f; line: 4, column: 8] (through reference chain: model.ClientInputMessage["date"])

【问题讨论】:

  • 尝试“日期”:“2014-01-01T00:00:00”。 Java 中的 LocalDateTime 不接受“2014-01-01”作为有效日期字符串。
  • @Jure Kolenko 哎呀,它有效
  • 对于仅日期值,例如“2014-01-01”,使用LocalDate 类而不是LocalDateTime 类。此外,如果您的问题得到解决,那么您或 Kolenko 应该发布一个答案以被接受以关闭此问题。
  • 老式的Date 类倾向于只使用一个日期,即使它确实包含一个时间点,即日期和时间(省去一些时区问题)。您可能认为这是一个功能或缺陷。新课程往往会迫使我们决​​定是否需要日期或时间或两者兼而有之。对我来说,这是迈向更好的一步。
  • @Jure Kolenko,请添加答案以接受

标签: java json spring date spring-boot


【解决方案1】:

原答案:

Java 中的 LocalDateTime 不接受“2014-01-01”作为有效日期字符串。

一些附加信息:

如果您实际上并不关心您的日期是什么类型(LocalDate、OffsetDate、ZonedDate,...),您可以将其设为 TemporalAccessor,然后使用 DateTimeFormatter::parseBest 解析日期。

附言
字符串“2014-01-01T00:00:00”对 LocalDateTime 有效

【讨论】:

  • 仅供参考:java.time 的类文档通常建议避免使用更通用的接口,例如TemporalAccessor。此类接口仅用于框架。引用: 这个接口是一个框架级接口,不应该在应用程序代码中广泛使用。相反,应用程序应该创建并传递具体类型的实例……
【解决方案2】:

您可以简单地告诉反序列化器,即使您在输出中有一个LocalDateTime,也应该是一个LocalDate,注意为您的LocalDate 有一个替代设置器变体

某事:

@JsonDeserialize(as = LocalDate.class)
@Past
private LocalDateTime date;

public void setDate(LocalDateTime input) {
    date = input;
}

public void setDate(LocalDate input) {
    date = input.atStartOfDay();
}

【讨论】:

    猜你喜欢
    • 2017-10-19
    • 1970-01-01
    • 2020-07-26
    • 1970-01-01
    • 2019-01-03
    • 2023-01-25
    • 2023-02-02
    • 1970-01-01
    • 2016-10-01
    相关资源
    最近更新 更多