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

新手上路,请多包涵

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

但是,如果有人试图反序列 2016-03-28T19:00:00.000+01:00 它将不起作用,因为 JavaTimeModule 似乎只会反序列化使用 UTC 时区偏移量格式化的日期时间(例如 2016-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"])

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

有没有办法在不编写自定义反序列化程序的情况下使用 Jackson 和 JavaTimeModule 将不在 UTC 时区偏移量中的 ISO8601 字符串反序列化为 Java 8 java.time.Instant

原文由 Krešimir Nesek 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.5k
2 个回答

您需要在模型类中通过 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)

原文由 Meiko Rachimow 发布,翻译遵循 CC BY-SA 4.0 许可协议

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

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

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

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

原文由 Guss 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题