issues with serialize LocalDate(Time)

5,966 views
Skip to first unread message

Chris C

unread,
Jul 21, 2018, 2:19:26 AM7/21/18
to jackson-user
I am using Java 8 and Jackon 2.9.6. I have these jars in my classpath :

j
ackson-annotations-2.9.6.jar
jackson
-core-2.9.6.jar
jackson
-databind-2.9.6.jar
jackson
-datatype-jdk8-2.9.6.jar
jackson
-datatype-jsr310-2.9.6.jar


I have the following classes (trimmed for simplicity) :

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, property = "@class")
public abstract class ContractData {

   
public String toJSON() {
       
try {
           
ObjectMapper mapper = new ObjectMapper();
            mapper
.registerModule(new Jdk8Module());
            mapper
.registerModule(new JavaTimeModule());

           
return new ObjectMapper().writeValueAsString(this);
       
}
       
catch (JsonProcessingException ex) {
           
throw new IllegalStateException("unable to write data as json", ex);
       
}
   
}

   
public static ContractData fromJSON(String json) {
       
try {
           
ObjectMapper mapper = new ObjectMapper();
            mapper
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
            mapper
.registerModule(new Jdk8Module());
            mapper
.registerModule(new JavaTimeModule());

           
return mapper.readValue(json, ContractData.class);
       
}
       
catch (IOException ex) {
           
throw new IllegalArgumentException("unable to convert json", ex);
       
}
   
}
}

public final class RegistrationContractData
extends ContractData
implements Serializable {

   
public static final long serialVersionUID = 1L;

   
private LocalDateTime created;

   
public RegistrationContractData() { }

   
public LocalDateTime getCreated() {
       
return this.created;
   
}

   
public void setCreated(LocalDateTime created) {
       
this.created = created;
   
}
}


If I serialize an instance of RegistrationContractData using the toJSON method, I get this :

"@class":"mypackage.contracts.data.RegistrationContractData","created":{"year":2018,"month":
"JULY","monthValue":7,"dayOfMonth":20,"hour":20,"minute":3,"second":33,"nano":653000000,"dayOfWeek":"FRIDAY","dayOfYear":201,"chronology":{"calendarType":"iso8601","id":"ISO"}}}


When I try and deserialize the string, I get this exception :

Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Expected array or string.
 at
[Source: (String)"{"@class":"mypackage.contracts.data.RegistrationContractData","created":{"year":2018,"month":"JULY","monthValue":7,"dayOfMonth":20,"hour":20,"minute":3,"second":33,"nano":653000000,"dayOfWeek":"FRIDAY","dayOfYear":201,"chronology":{"calendarType":"iso8601","id":"ISO"}}}"; line: 1, column: 95] (through reference chain: mypackage.contracts.data.RegistrationContractData["created"])
        at com
.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63) ~[jackson-databind-2.9.6.jar:2.9.6]
        at com
.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1342) ~[jackson-databind-2.9.6.jar:2.9.6]
        at com
.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1138) ~[jackson-databind-2.9.6.jar:2.9.6]
        at com
.fasterxml.jackson.datatype.jsr310.deser.JSR310DeserializerBase._handleUnexpectedToken(JSR310DeserializerBase.java:99) ~[jackson-datatype-jsr310-2.9.6.jar:2.9.6]
        at com
.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer.deserialize(LocalDateTimeDeserializer.java:141) ~[jackson-datatype-jsr310-2.9.6.jar:2.9.6]
        at com
.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer.deserialize(LocalDateTimeDeserializer.java:39) ~[jackson-datatype-jsr310-2.9.6.jar:2.9.6]
        at com
.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:127) ~[jackson-databind-2.9.6.jar:2.9.6]
        at com
.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288) ~[jackson-databind-2.9.6.jar:2.9.6]
        at com
.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:189) ~[jackson-databind-2.9.6.jar:2.9.6]
        at com
.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:161) ~[jackson-databind-2.9.6.jar:2.9.6]
        at com
.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer._deserializeTypedForId(AsPropertyTypeDeserializer.java:130) ~[jackson-databind-2.9.6.jar:2.9.6]
        at com
.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer.deserializeTypedFromObject(AsPropertyTypeDeserializer.java:97) ~[jackson-databind-2.9.6.jar:2.9.6]
        at com
.fasterxml.jackson.databind.deser.AbstractDeserializer.deserializeWithType(AbstractDeserializer.java:254) ~[jackson-databind-2.9.6.jar:2.9.6]
        at com
.fasterxml.jackson.databind.deser.impl.TypeWrappedDeserializer.deserialize(TypeWrappedDeserializer.java:68) ~[jackson-databind-2.9.6.jar:2.9.6]
        at com
.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013) ~[jackson-databind-2.9.6.jar:2.9.6]
        at com
.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3004) ~[jackson-databind-2.9.6.jar:2.9.6]
        at mypackage
.contracts.data.ContractData.fromJSON(ContractData.java:36) ~[tx-core.jar:na]
       
... 45 common frames omitted


If I instead annotate the LocalDateTime field as

    @JsonSerialize(using = LocalDateTimeSerializer.class)
   
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
   
private LocalDateTime created;


I get the following serialized output

{"@class":"mypackage.contracts.data.RegistrationContractData","created":[2018,7,20,20,9,20,938000000]}

which deserializes properly. If I keep the field annotated and remove the ObjectMapper.registerModule() calls, it still works. I get the same error for a LocalDate as a LocalDateTime. I haven't tried anything specific to Java 8+ yet.

From what I could glean off older stack exchange posts I am supposed to use ObjectMapper.registerModule with this version instead of the annotations. What have I missed? Why is it not deserializing properly?

Thanks

Chris C

unread,
Jul 21, 2018, 9:00:12 AM7/21/18
to jackson-user
/facepalm

As soon as I posted this and returned to the code, I saw the problem. In toJSON() I am creating an ObjectMapper, registering the modules, and then ignoring that and creating a new one to do the serialization.

Sorry for the brain fart.

Tatu Saloranta

unread,
Jul 24, 2018, 11:01:11 PM7/24/18
to jackson-user
On Sat, Jul 21, 2018 at 6:00 AM, Chris C <yahoo...@gmail.com> wrote:
> /facepalm
>
> As soon as I posted this and returned to the code, I saw the problem. In
> toJSON() I am creating an ObjectMapper, registering the modules, and then
> ignoring that and creating a new one to do the serialization.

That explains it: serialization indeed looks like java 8 date-time
module was not registered.

>
> Sorry for the brain fart.

Happens to the best of us :)

Thank you for sharing the story,

-+ Tatu +-
> --
> You received this message because you are subscribed to the Google Groups
> "jackson-user" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to jackson-user...@googlegroups.com.
> To post to this group, send email to jackso...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

kaushik tiwari

unread,
Oct 27, 2020, 12:33:24 PM10/27/20
to jackson-user
hey, what if I want to deserialized the same json which u mentioned in this post.
I have one problem statement on that. Let me know if u have figure out something


{"year":2018,"month":
"JULY","monthValue":7,"dayOfMonth":20,"hour":20,"minute":3,"second":33,"nano":653000000,"dayOfWeek":"FRIDAY","dayOfYear":201,"chronology":{"calendarType":"iso8601","id":"ISO"}} 

Reply all
Reply to author
Forward
0 new messages