繁体   English   中英

使用 Jackson 反序列化 Java 8 LocalDateTime

[英]Deserialize Java 8 LocalDateTime with Jackson

在 Jackson 2.11 中,在序列化过程中更改了 LocalDataTime 格式。 我有反序列化的问题。 我找到了从 objectMapper 覆盖配置的解决方案,如下所示:

@Configuration
public class AppConfig {

    @Bean
    public ObjectMapper objectMapper()
    {
        ObjectMapper mapper = new ObjectMapper();
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        mapper.registerModule(javaTimeModule);
        return mapper;
    }

但我仍然无法将 json 字符串反序列化为 java model:

@Data
public class CustomLocalDataTime {


    //@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSxxx") <- not working
    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS") // <- not working
    // @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", shape = JsonFormat.Shape.STRING) <- not working
    private  LocalDateTime date;
}

所以我从格式示例中的一些响应 localdatatime 收到:2022-04-05T05:00:00.000+00:00 并且在反序列化期间我仍然收到错误:

    com.fasterxml.jackson.databind.exc.InvalidFormatException: 
    Cannot deserialize value of type `java.time.LocalDateTime` 
    from String "2022-04-05T05:00:00.000+00:00": Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException) Text '2022-04-05T05:00:00.000+00:00' 
could not be parsed, unparsed text found at index 23
         at [Source: (String)"{"date":"2022-04-05T05:00:00.000+00:00"}"; line: 1, column: 9]

我通过这样重现此错误来接收此错误:

@PostConstruct
public void customDeserializeTest() {
    String content =
        "{\"date\":\"2022-04-05T05:00:00.000+00:00\"}";
    try {
        CustomLocalDataTime customLocalDataTime = objectMapper.readValue(content, CustomLocalDataTime.class);
    } catch (JsonProcessingException e) {
        e.printStackTrace();
    }
}

我也尝试添加: com.fasterxml.jackson.databind.annotation。

@JsonDeserialize(using = LocalDateTimeDeserializer.class)

但这也行不通。

非常感谢您的指导。

数据类型错误

正如其他人评论的那样,您使用了错误的数据类型。

LocalDateTime class 故意缺少任何时区offset-from-UTC 的概念。 所以这个 class 不能代表 moment ,时间轴上的特定点。 这个 class 仅代表日期和时间,但我们不知道该日期和时间是用于日本东京、法国图卢兹还是美国俄亥俄州托莱多。

因此LocalDateTime class 不适合您的输入。

字符串输入:

  • 2022-04-05T05:00:00.000+00:00
  • 2022-04-05T05:00:00.000Z

…两者都代表 UTC 中的时刻,与 UTC 的偏移量为零小时-分钟-秒。 第二个结尾的Z+00:00的标准 ISO 8601 缩写,发音为“Zulu”。

InstantOffsetDateTime

您可以将此类输入解析为Instant对象或更灵活OffsetDateTime对象。

这些输入字符串使用标准ISO 8601格式。 java.time类在解析/生成时默认使用这些格式。 因此无需指定格式化模式。

Instant instant = Instant.parse( "2022-04-05T05:00:00.000+00:00" ) ;
Instant instant2 = Instant.parse( "2022-04-05T05:00:00.000Z" ) ;

OffsetDateTime odt = OffsetDateTime.parse( "2022-04-05T05:00:00.000+00:00" ) ;
OffsetDateTime odt2 = OffsetDateTime.parse( "2022-04-05T05:00:00.000Z" ) ;

请参阅在 IdeOne.com 上实时运行的代码

instant: 2022-04-05T05:00:00Z
instant2: 2022-04-05T05:00:00Z
odt: 2022-04-05T05:00Z
odt2: 2022-04-05T05:00Z

一条评论提到使用ZonedDateTime 那将是不明智的。 时区的名称采用Continent/Region格式,例如Europe/ParisPacific/Auckland 您的输入只有偏移量,没有时区。 所以ZonedDateTime在这里会产生误导和混淆。

偏移量仅仅是UTC本初子午线之前或之后的小时-分钟-秒数。 时区要多得多。 时区是特定地区的人们使用的偏移量的过去、现在和未来变化的命名历史。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM