给定格式的带有UTC时区的JacksonMapper日期反序列化失败

时间:2018-11-19 22:14:21

标签: java jackson fasterxml java-date

我知道关于同一问题有很多重复的问题,但是,我无法将给定的日期格式反序列化为java.util.Date对象。我正在使用的客户端api返回的6位数字与毫秒和纳秒相结合的日期字段。

  • 2016-12-08T20:09:05.508883Z
  • 2016-12-08T20:09:05.527Z

有时它包括纳秒,有时不包括。我尝试遵循jackson-databind库本身的反序列化示例,但是找不到解决方法。说这是示例json blob

{
    "id": "68e6a28f-ae28-4788-8d4f-5ab4e5e5ae08",
    "created_at": "2016-12-08T20:09:05.508883Z",
    "done_at": "2016-12-08T20:09:05.527Z"
}

Entity.java

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class OrderResponse {
    private String id;

    @JsonProperty("created_at")
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss'*'", timezone = "UTC")
    private Date createdAt;

    @JsonProperty("done_at")
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss'*'", timezone = "UTC")
    private Date doneAt;
}

如果我仅使用格式yyyy-MM-dd'T'HH:mm:ss,杰克逊映射器将反序列化来自jvm本身的时区。但是我需要使用UTC格式,并且我还尝试实现自定义反序列化器和序列化器,但效果不佳。我的问题是java.util.Date的对象类型正确吗?另外,我还尝试通过注册new JavaTimeModule()来创建自己的对象映射器,但是没有用。

感谢帮助。

1 个答案:

答案 0 :(得分:1)

我发现java.time.format.DateTimeFormatter的格式类型为ISO_INSTANT,它支持我想要的格式。

https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ISO_INSTANT

基本上,我写了我的自定义解串器

public class CustomInstantDeserializer extends JsonDeserializer<Instant> {

    private DateTimeFormatter fmt = DateTimeFormatter.ISO_INSTANT.withZone(ZoneOffset.UTC);

    @Override
    public Instant deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        return Instant.from(fmt.parse(p.getText()));
    }
}

在相关字段上带有@JsonDeserialize注释。

@JsonProperty("created_at")
@JsonDeserialize(using = CustomInstantDeserializer.class)
private Instant createdAt;