8

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?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
jlp
  • 1,656
  • 6
  • 33
  • 48
  • `InstantDeserializer.class` is custom deserializer class?, if i believe in that class you may declared some arg constructor without no-arg constructor – Ryuzaki L Nov 09 '18 at 20:08
  • @Deadpool no, it is not a custom class.. com.fasterxml.jackson.datatype.jsr310.deser – jlp Nov 09 '18 at 20:10
  • what does your POM look like? – Darren Forsythe Nov 09 '18 at 20:15
  • @DarrenForsythe Just updated above with the dependency. Were you looking for something else in the pom.xml? – jlp Nov 09 '18 at 20:50
  • Have you tried `@JsonDeserialize(using = InstantDeserializer.INSTANT)` instead? – Julio Daniel Reyes Nov 09 '18 at 21:15
  • @JulioDanielReyes I just tried and I got a compiler error -- Type mismatch: cannot convert from InstantDeserializer to Class extends JsonDeserializer> – jlp Nov 09 '18 at 21:22
  • 1
    Look at this answer https://stackoverflow.com/a/45215515/4727666, you need a class with a constructor that takes no arguments, so you can extend InstantDeserializer to create your own. – Julio Daniel Reyes Nov 09 '18 at 21:31
  • 1
    For the arguments, take a look at this https://github.com/FasterXML/jackson-datatype-jsr310/blob/master/src/main/java/com/fasterxml/jackson/datatype/jsr310/deser/InstantDeserializer.java#L53 – Julio Daniel Reyes Nov 09 '18 at 21:35
  • @JulioDanielReyes Thank you very much. I will take a look – jlp Nov 09 '18 at 21:40
  • @JulioDanielReyes still doesn't work after adding the constructor. – jlp Nov 10 '18 at 19:27

1 Answers1

13

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)
Julio Daniel Reyes
  • 5,489
  • 1
  • 19
  • 23