ZonedDateTime

时间:2016-01-13 10:34:56

标签: java json spring jackson jsr310

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

private ZonedDateTime transactionDateTime;

我消费的服务可能会使用以下模式返回日期或日期时间:yyyy-MM-dd'T'HH:mm:ss.SSSZ

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

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

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

  

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

我正在使用;

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

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

4 个答案:

答案 0 :(得分:3)

您可以使用以下注释:

@JsonSerialize(using = MyCustomJsonDateSerializer.class)

@JsonDeserialize(using = MyCustomJsonDateDeserializer.class)

定制杰克逊如何解析日期。那些自定义的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);
      }
}

答案 1 :(得分:2)

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

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

  

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

该字段的编写如下:

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

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

答案 2 :(得分:0)

jackson反序列化默认情况下会通过传递时区infor并使用ctx时区覆盖它,所有ISO8601将以UTC结尾

如果您在春季,可以通过关闭此功能 spring.jackson.deserialization.ADJUST_DATES_TO_CONTEXT_TIME_ZONE = false

答案 3 :(得分:0)

我用过

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
private ZonedDateTime startDate;

加上jackson-datatype-jsr310库,显然。

此解决方案在Jackson deserialize ISO8601 formatted date-time into Java8 Instant

中进行了描述