java ZonedDateTime 的 Jackson 反序列化问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34764355/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hymanson deserialization issue for ZonedDateTime
提问by tunix
I've the following field in a class I use during deserialization of a service that I'm consuming.
我在我正在消费的服务的反序列化期间使用的类中有以下字段。
private ZonedDateTime transactionDateTime;
The service I'm consuming may return a Date or DateTime using the pattern: yyyy-MM-dd'T'HH:mm:ss.SSSZ
我正在使用的服务可能会使用以下模式返回 Date 或 DateTime: yyyy-MM-dd'T'HH:mm:ss.SSSZ
Let me give 2 examples of what the service returns:
让我举两个服务返回的例子:
- 2015-11-18T18:05:38.000+0200
- 2015-11-18T00:00:00.000+0200
- 2015-11-18T18:05:38.000+0200
- 2015-11-18T00:00:00.000+0200
While first one works well, the latter causes the following exception to be thrown during deserialization:
虽然第一个运行良好,但后者会导致在反序列化过程中抛出以下异常:
java.time.format.DateTimeParseException: Text '2015-11-18T00:00:00.000+0200' could not be parsed at index 23
java.time.format.DateTimeParseException:无法在索引 23 处解析文本“2015-11-18T00:00:00.000+0200”
I'm using;
我正在使用;
- Spring Boot 1.3.1
- Hymanson 2.6.4 (with JSR310 module included)
- 弹簧靴 1.3.1
- Hymanson 2.6.4(包含 JSR310 模块)
Does this require a custom deserialization class?
这是否需要自定义反序列化类?
采纳答案by tunix
Earlier in the code I was using the field with @JsonFormat
annotation but removed that as I thought it was meant for serialization only like the JavaDocs suggest.
在代码的早些时候,我使用带有@JsonFormat
注释的字段,但删除了它,因为我认为它仅用于序列化,就像 JavaDocs 建议的那样。
Turned out that I needed add back that annotation. And the real issue was that the 3rd party service response was indeed wrong (it was missing a wrapper element in the XML) which caused the deserialisation to fail. The error was:
原来我需要加回那个注释。真正的问题是第 3 方服务响应确实是错误的(它在 XML 中缺少包装元素)导致反序列化失败。错误是:
com.fasterxml.Hymanson.databind.JsonMappingException: Can not instantiate value of type [simple type, class com.foo.bar.adapter.john.model.account.UserAccount] from String value ('2015-11-18T00:00:00.000+0200'); no single-String constructor/factory method
com.fasterxml.Hymanson.databind.JsonMappingException:无法从字符串值('2015-11-18T00:00: 00.000+0200'); 没有单字符串构造函数/工厂方法
The field is written like below:
该字段的写法如下:
@JsonFormat(pattern = Constants.DATETIME_FORMAT)
@HymansonXmlProperty(localName = "transactionDate")
private ZonedDateTime transactionDateTime;
Also I had to add @JsonRootName("transaction")
to the class of this field because the object is wrapped into a collection.
此外,我必须添加@JsonRootName("transaction")
到该字段的类中,因为该对象被包装到一个集合中。
回答by Ricardo Vila
You can use annotations like:
您可以使用以下注释:
@JsonSerialize(using = MyCustomJsonDateSerializer.class)
or
或者
@JsonDeserialize(using = MyCustomJsonDateDeserializer.class)
To customize how Hymanson parses Dates. Those custom Serializer and Deserializer must extend JsonSerializer and JsonDeserializer. For example:
自定义 Hymanson 解析日期的方式。那些自定义的 Serializer 和 Deserializer 必须扩展 JsonSerializer 和 JsonDeserializer。例如:
public class MyCustomJsonDateSerializer extends JsonSerializer<Date> {
@Override
public void serialize(Date date, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeString(date != null ? ISODateTimeFormat.dateTime().print(new DateTime(date)) : null);
}
}
回答by Jiajun Cui
Hymanson deserialize will by default to by pass the timezone infor and use ctx timezone to overrride it ,which all ISO8601 will ends to UTC
Hymanson 反序列化将默认绕过时区信息并使用 ctx 时区覆盖它,所有 ISO8601 都将结束为 UTC
this feature can be turned off by ,if you are on spring
如果您在春季,可以通过以下方式关闭此功能
spring.Hymanson.deserialization.ADJUST_DATES_TO_CONTEXT_TIME_ZONE=false
回答by Vladimir Rozhkov
I've used
我用过
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
private ZonedDateTime startDate;
plus Hymanson-datatype-jsr310
library, obviously.
Hymanson-datatype-jsr310
显然,加上图书馆。
This solution is described in Hymanson deserialize ISO8601 formatted date-time into Java8 Instant
Hymanson deserialize ISO8601 formatted date-time into Java8 Instant描述了这个解决方案