简体   繁体   中英

Use Jackson ObjectMapper to convert between java.time.Instant and java.util.Date

I'm trying to use Jackson's ObjectMapper to map between two classes (SrcMessage and DestMessage, for example).

My SrcMessage class looks something like:

class SrcMessage {
        public Instant workTime;
}

My DestMessage class looks like:

class DestMessage {
   public Date workTime;
}

I'm using the ObjectMapper like so:

SrcMessage src = new SrcMessage ();
src.workTime = Instant.now ();

ObjectMapper mapper = new ObjectMapper ( );
mapper.registerModule (new JavaTimeModule ());

DestMessage dest = mapper.convertValue (src, DestMessage.class);

When I make the convertValue call I get an exception with a message:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.Date` out of VALUE_NUMBER_FLOAT token
 at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: DestMessage["workTime"])
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
    at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1468)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1242)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1148)
    at com.fasterxml.jackson.databind.deser.std.StdDeserializer._parseDate(StdDeserializer.java:517)
    at com.fasterxml.jackson.databind.deser.std.DateDeserializers$DateBasedDeserializer._parseDate(DateDeserializers.java:200)
    at com.fasterxml.jackson.databind.deser.std.DateDeserializers$DateDeserializer.deserialize(DateDeserializers.java:290)
    at com.fasterxml.jackson.databind.deser.std.DateDeserializers$DateDeserializer.deserialize(DateDeserializers.java:273)
    at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:138)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:293)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:156)
    at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:4231)

I'm stuck. I thought that the JavaTimeModule would be enough to handle this conversion, but apprently not. Is there some other module that I need? Other suggestions on how to make this work? So far the only solution I've found is to ignore the workTime field when doing the mapping, and then convert the value after the mapper has completed. Needless to say, this works for a simple case, but I'd rather not have to enumerate all of the Instant/Date fields and handle them manually. I'd much rather have Jackson handle it internally.

Any ideas?

For converting dates I would recommend using benefits of types, instead of using Jackson ObjectMapper. Use Date from(Instant instant) static method to convert java.time.Instant type into java.util.Date type.

You can do it as presented in example:

import java.time.Instant;
import java.util.Date;

public class StackOverflowAnswer {
    public static void main(String[] args) {
        SrcMessage srcMessage = new SrcMessage(Instant.now());
        DestMessage destMessage = DestMessage.fromSrcMessage(srcMessage);
    }
}

class SrcMessage {
    public Instant workTime;

    public SrcMessage(Instant workTime) {
        this.workTime = workTime;
    }
}

class DestMessage {
    public Date workTime;

    DestMessage(Date workTime) {
        this.workTime = workTime;
    }

    static DestMessage fromSrcMessage(SrcMessage srcMessage) {
        return new DestMessage(Date.from(srcMessage.workTime));
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM