How to disable Jackson from deserializing an Instant from epoch millis?

16
May 16, 2019, at 6:40 PM

I am developing an API using Spring Boot and am using Jackson for payload (de)serialization. I want to deserialize an ISO-8601 formatted datetime into a java.time.Instant, but do not want to support deserializing from epoch time in milliseconds or nanoseconds. I want to only support the data being provided to my API in one format to reduce the chance of client error.

Currently, Jackson deserializes to an Instant from both an ISO-8601 formatted string AND from a string containing only numbers e.g. "20190520".

Are there Jackson annotations I can use on my Instant field, or properties I can set to apply this kind of behaviour? Or is a custom deserializer my only option?

Answer 1

Are there Jackson annotations I can use on my Instant field, or properties I can set to apply this kind of behaviour? Or is a custom deserializer my only option?

I am not personally aware of annotations that will do this out-of-the-box for you; but the following is a simple deserializer that does the job:

import java.io.IOException;
import java.time.Instant;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
public class JacksonInstantDeserializer extends StdDeserializer<Instant> {
    public JacksonInstantDeserializer() { this(null); }
    public JacksonInstantDeserializer(Class<?> clazz) { super(clazz); }
    @Override
    public Instant deserialize(JsonParser parser, DeserializationContext ctx) throws IOException {
        return Instant.parse(parser.getText());
    }
}

It basically uses Instant.parse; which accepts ONLY an ISO-8601 formatted string (it will throw a DateTimeParseException if the string is not formatted accordingly) and creates an Instant based on its representation. Then you can use tell jackson to use this converter to deserialize the Instant properties of your DTOs in the following manner:

    public class MyDTO {
        @JsonDeserialize(using = JacksonInstantDeserializer.class)
        public Instant instant;
    }

Hope this helps.

READ ALSO
what does it mean BuildConfig.FLAVOR in this code

what does it mean BuildConfig.FLAVOR in this code

I need some Help about BuildConfigFLAVOR

24
How can I make a list still contain its elements even after clearing it?

How can I make a list still contain its elements even after clearing it?

How should I go about setting a key to a list in a foreach loop and then reseting aforementioned list so it takes in other values without clearing it

33
How can I run wsgen ant task natively in Kotlin dsl?

How can I run wsgen ant task natively in Kotlin dsl?

I am converting existing groovy based gradle task into kotlin, following approach is painfully slowIs there an alternative approach to what I have so far?

14
How I can write a function returns a deep copy of the three dimensional array at the index in Java?

How I can write a function returns a deep copy of the three dimensional array at the index in Java?

In this assigment, you have to implement a simple tour planing systemThe data for the available tours, each with multiple way points, is statically given

41