使用Jackson反序列化Java 8本地日期时间

zaqlnxep  于 2022-11-09  发布在  Java
关注(0)|答案(1)|浏览(134)

在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模型方面仍然存在问题:

@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;
}

所以我从一些响应localdatetime接收格式示例:2022-04- 05 T05: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();
    }
}

我还试着补充一句:* 数据绑定注解。*

@JsonDeserialize(using = LocalDateTimeDeserializer.class)

但这也是行不通的。
非常感谢您的指导。

wpcxdonn

wpcxdonn1#

错误的数据类型

正如其他人所评论的,您使用了错误的数据类型。
LocalDateTime类故意缺少time zoneoffset-from-UTC的任何概念。因此该类不能表示时刻,即时间线上的特定点。该类仅表示日期和时间,但我们不知道该日期和时间是针对日本东京、法国图卢兹还是美国俄亥俄州托莱多。
因此LocalDateTime类不适合您的输入。
字符串输入:

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

...两者都表示UTC中的一个时刻,与UTC的偏移量为零时-分-秒。第二个末尾的Z+00:00的标准ISO 8601缩写,发音为“Zulu”。
第1006章:一个人
您可以将这两种输入解析为Instant对象或更灵活的OffsetDateTime对象。
这些输入字符串使用标准的ISO 8601java.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" ) ;

见此code run live at 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本初子午线前后的时-分-秒数,而时区的意义则要大得多。时区是一个特定地区的人们所使用的过去、现在和未来的时差变化的命名历史。

相关问题