如何解决Spring - 无法使用 WebClient 或 ObjectMapper 将字符串反序列化为 ZonedDateTime
我在 Kotlin/Spring 中遇到了一个关于日期变量的奇怪问题。我有两个应用程序的服务。一个“逻辑”后端和一个处理数据库插入的纯数据库 API 服务。逻辑后端用 Kotlin 编写,数据库服务在 Node 中运行。我使用WebClient来请求数据库服务,配置为一个bean,在多个服务之间共享。
问题是关于从数据库服务反序列化具有 (UTC) 时区的日期。在将日期传递给数据库 API 时序列化日期的工作与预期一样,但是当它收到相同的数据时,一旦序列化它就会返回此错误。
java.time.format.DateTimeParseException: Text '2021-03-10T12:45:00.000Z' Could not be parsed at index 23
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046) ~[na:na]
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1874) ~[na:na]
at com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer._fromString(InstantDeserializer.java:282) ~[jackson-datatype-jsr310-2.12.2.jar:2.12.2]
...
如果我理解正确的话,它有一些时区问题(索引 23 等于 Z)。但后来我不明白为什么它可以毫无问题地进行序列化?
来自后端的请求:
val students = webClient
.get()
.uri("/students")
.retrieve()
.bodyToMono(Array<Student>::class.java)
.block(Duration.ofSeconds(ApiConstants.REQUEST_TIMEOUT))!!
我已应用 JsonFormat 注释使其以一种方式工作,但另一种方式不起作用。
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX",shape = JsonFormat.Shape.STRING)
val date: zoneddatetime = zoneddatetime.Now(),
我还尝试获取纯 JSON 字符串并使用 jacksonObjectMapper 对其进行解析,但结果相同。我还应用了 JavaTimeModule 却没有结果。
我还尝试创建自定义反序列化器并在 this example 之后使用 JsonSerialize 和 Deserialize 注释 zoneddatetime 字段,但这只会导致另一个错误。这让我开始怀疑杰克逊是否是这里的问题。
java.lang.NoSuchMethodError: 'boolean com.fasterxml.jackson.databind.SerializationConfig.hasExplicitTimeZone()'
at com.fasterxml.jackson.datatype.jsr310.ser.InstantSerializerBase.formatValue(InstantSerializerBase.java:144) ~[jackson-datatype-jsr310-2.12.2.jar:2.12.2]
at com.fasterxml.jackson.datatype.jsr310.ser.InstantSerializerBase.serialize(InstantSerializerBase.java:103) ~[jackson-datatype-jsr310-2.12.2.jar:2.12.2]
...
更新
所以,问题出在杰克逊身上。由于后端设法自己读取值而没有任何问题,因此它不会以良好的方式创建 JSON 输出。
所以,我找到了解决方案。虽然不是什么好看的。这里的逻辑是我让 Spring/Jackson 根据需要读入变量,我只允许 Jackson 写入它,然后我有一个单独的 getter 方法在 JSON 输出中创建缺失的字段。
但我真的很想解决原来的问题,因为这个解决方案显然更容易出错。
@JsonIgnoreProperties(ignoreUnkNown = true)
data class Order(
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
val date: zoneddatetime = zoneddatetime.Now(),) {
val outputDate: zoneddatetime
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX",shape = JsonFormat.Shape.STRING)
@JsonProperty("date")
get() = this.date
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。