Search code examples
javajsonjacksonfasterxmljsr310

Java 8 Exception: com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer has no default (no arg) constructor


I have a model class that has a field:

 @JsonDeserialize(using = InstantDeserializer.class)
 @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ")
 private OffsetDateTime offsetDt;

When a request of this model is sent to the server, my controller throws an exception:

Caused by: java.lang.IllegalArgumentException: 
Class com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer 
has no default (no arg) constructor

The pom.xml has the dependency of version 2.8.11:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

I understand that it is caused by @JsonDeserialize requiring no-arg constructor, but is there a workaround?


Solution

  • The error says that you need a class with no arg constructor, so you could extend from InstantDeserializer. (Take as example the code in InstantDeserializer for the arguments of super())

    public class DefaultInstantDeserializer extends InstantDeserializer<OffsetDateTime> {
        public DefaultInstantDeserializer() {
            super(OffsetDateTime.class, DateTimeFormatter.ISO_OFFSET_DATE_TIME,
                    OffsetDateTime::from,
                    a -> OffsetDateTime.ofInstant(Instant.ofEpochMilli(a.value), a.zoneId),
                    a -> OffsetDateTime.ofInstant(Instant.ofEpochSecond(a.integer, a.fraction), a.zoneId),
                    (d, z) -> d.withOffsetSameInstant(z.getRules().getOffset(d.toLocalDateTime())),
                    true);
        }
    }
    

    Then you can use it:

    @JsonDeserialize(using = DefaultInstantDeserializer.class)