quartaela
quartaela

Reputation: 2757

JacksonMapper Date deserialization with UTC time zone fails with given format

I know there are many duplicate questions about the same issue, however, I wasn't able to deserialize given date format into java.util.Date object. The client api I am using returns date fields with 6 digit combined with milliseconds and nanoseconds.

Sometimes it includes nano seconds sometimes not. I tried to follow deserialization examples from jackson-databind library itself however couldn't found a workaround. Say this is the example 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;
}

If I only use format yyyy-MM-dd'T'HH:mm:ss jackson mapper deserializes with timezone coming from jvm itself. But I need to use UTC format and I tried also implementing custom deserializer and serializer which doesn't work as well. My question is java.util.Date correct object type? Additionally, I also tried to create my own object mapper with registering new JavaTimeModule() but it didn't work.

Thanks for help.

Upvotes: 3

Views: 2430

Answers (1)

quartaela
quartaela

Reputation: 2757

I found that java.time.format.DateTimeFormatter has ISO_INSTANT format type which supports the format I was looking for.

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

Basically, I wrote my custom deserializer

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

with @JsonDeserialize annotation on related field.

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

Upvotes: 3

Related Questions