Jackson deserialization issue for ZonedDateTime

与世无争的帅哥 提交于 2019-12-10 04:17:19

问题


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

Let me give 2 examples of what the service returns:

  • 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

I'm using;

  • Spring Boot 1.3.1
  • Jackson 2.6.4 (with JSR310 module included)

Does this require a custom deserialization class?


回答1:


You can use annotations like:

@JsonSerialize(using = MyCustomJsonDateSerializer.class)

or

@JsonDeserialize(using = MyCustomJsonDateDeserializer.class)

To customize how Jackson parses Dates. Those custom Serializer and Deserializer must extend JsonSerializer and JsonDeserializer. For example:

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



回答2:


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.

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:

com.fasterxml.jackson.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

The field is written like below:

@JsonFormat(pattern = Constants.DATETIME_FORMAT)
@JacksonXmlProperty(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.




回答3:


Jackson deserialize will by default to by pass the timezone infor and use ctx timezone to overrride it ,which all ISO8601 will ends to UTC

this feature can be turned off by ,if you are on spring

spring.jackson.deserialization.ADJUST_DATES_TO_CONTEXT_TIME_ZONE=false


来源:https://stackoverflow.com/questions/34764355/jackson-deserialization-issue-for-zoneddatetime

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!