ZonedDateTime的jackson反序列化问题

我在我正在使用的服务的反序列化过程中使用的类中有以下字段。

private ZonedDateTime transactionDateTime; 

我正在使用的服务可以使用以下模式返回Date或DateTime: yyyy-MM-dd'T'HH:mm:ss.SSSZ

让我举两个服务返回的例子:

  • 2015-11-18T18:05:38.000 + 0200
  • 2015-11-18T00:00:00.000 + 0200

虽然第一个工作正常,但后者导致在反序列化期间抛出以下exception:

java.time.format.DateTimeParseException:无法在索引23处解析文本’2015-11-18T00:00:00.000 + 0200′

我正在使用;

  • Spring Boot 1.3.1
  • Jackson 2.6.4(包含JSR310模块)

这需要自定义反序列化类吗?

您可以使用以下注释:

 @JsonSerialize(using = MyCustomJsonDateSerializer.class) 

要么

 @JsonDeserialize(using = MyCustomJsonDateDeserializer.class) 

定制jackson如何解析日期。 那些自定义的Serializer和Deserializer必须扩展JsonSerializer和JsonDeserializer。 例如:

 public class MyCustomJsonDateSerializer extends JsonSerializer { @Override public void serialize(Date date, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { jgen.writeString(date != null ? ISODateTimeFormat.dateTime().print(new DateTime(date)) : null); } } 

在代码的早期,我使用带有@JsonFormat注释的字段但删除了它,因为我认为它仅用于序列化,就像JavaDocs建议的那样。

原来我需要添加那个注释。 真正的问题是第三方服务响应确实是错误的(它缺少XML中的包装元素)导致反序列化失败。 错误是:

com.fasterxml.jackson.databind.JsonMappingException:无法从字符串值(’2015-11-18T00:00:’实例化类型[simple type,class com.foo.bar.adapter.john.model.account.UserAccount]的值。 00.000 + 0200′ ); 没有单字符串构造函数/工厂方法

该字段的编写如下:

 @JsonFormat(pattern = Constants.DATETIME_FORMAT) @JacksonXmlProperty(localName = "transactionDate") private ZonedDateTime transactionDateTime; 

此外,我必须将@JsonRootName("transaction")添加到此字段的类中,因为该对象已包装到集合中。

jackson deserialize默认情况下会通过时区infor并使用ctx timezone来覆盖它,所有ISO8601都将结束为UTC

如果你在spring,你可以关闭这个function.jackson.deserialization.ADJUST_DATES_TO_CONTEXT_TIME_ZONE = false