Jackson 将 ISO8601 格式的日期时间反序列化为 Java8 Instant

2022-08-31 15:52:41

我正在尝试使用Jackson将ISO8601格式的日期反序列化为Java8。我向 ObjectMapper 注册了 JavaTimeModule,并关闭了该设置。java.time.InstantWRITE_DATES_AS_TIMESTAMPS

但是,如果尝试反序列化,它将不起作用,因为JavaTimeModule似乎只会反序列化使用UTC时区偏移量格式化的日期时间(例如)。然后我尝试使用这样的注释:2016-03-28T19:00:00.000+01:002016-03-28T18:00:00.000Z@JsonFormat

@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "UTC")

像这样:

@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = JsonFormat.DEFAULT_TIMEZONE)

但是,这两者都不起作用,我得到一个例外:

com.fasterxml.jackson.databind.JsonMappingException: Unsupported field: YearOfEra (through reference chain: org.example.Article["date"])

这意味着时区参数被忽略,日期时间格式化程序不知道如何在没有时区的即时格式。

有没有办法使用 Jackson 和 JavaTimeModule 反序列化不在 UTC 时区偏移到 Java 8 的 ISO8601 字符串,而无需编写自定义反序列化程序?java.time.Instant


答案 1

您需要在 modell 类中设置显式时区:XXX

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")

(请参阅:https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html)


答案 2

如果要将对象序列化为 ISO-8601,则根本不需要指定模式 - ISO-8601 是默认模式。在JsonFormat Java文档中提到了它:Date

常见用途包括在备用表示形式之间进行选择 - 例如,日期是序列化为数字(Java 时间戳)还是字符串(例如 ISO-8601 兼容时间值) - 以及使用 pattern() 属性配置确切的详细信息。

[强调我的]您应该从上面的文本中了解指定将意味着ISO-8601格式,但您可以使用该属性选择其他格式。shape = STRINGpattern

根据我的经验,这总是会出现 UTC 日期格式(时区呈现为 ),这可能是 VM 中的默认时区(即使我的操作系统时钟未设置为 UTC)。+0000