1

I'm serializing some java.util.Dates within a Map. The dates are serialized into Longs (Jackson writes the Long value of the Date instance to the JSON string), however, they're not being de-serialized back to Date instances, but as Long instances.

I'd like Jackson to de-serialize the dates back to Date objects (rather than formatted Strings or Longs), how can I achieve this?

Map<String, Comparable<?>> change = new HashMap<String, Comparable<?>>();
    change.put("DESCRIPTION", "LIBOR");
    change.put("RATE", "1.8");
    change.put("DATE", Util.newDate(2009, 7, 1)); // Returns a java.util.Date

Produces

{"DESCRIPTION":"LIBOR"},{"RATE":"1.8"},{"DATE":1246402800000}, ... }

Which is okay. However, the date String is deserialized (inflated) back into an instance of java.lang.Long, when I want it to be an instance of java.util.Date - which is what it started as. i.e. Map change now contains three entries; Description as a String, Rate as a Float and Date as a Long.

JoshSnow
  • 23
  • 1
  • 1
  • 4
  • You need to include deserialization code: my guess is you are not giving generinc information. If your map can contain any Comparables, deserializer can not know what type you expect: so "natural" type for JSON number is long, int or double (depending on if it's floating point value, its length). This is why it gets back as Long. So you must be able to indicate type. There are many ways to do this, and I can help more, just need more info. – StaxMan Mar 31 '11 at 17:15
  • @JoshSnow Login under Open-Id used by @Josh and you will be – abatishchev Apr 14 '11 at 14:06
  • @StaxMan - Thanks for your reply and apologies for not replying sooner. Due to project deadlines, I had to abandon using Jackson and implement an Entity based approach instead. (I was going to save the JSON string in the database). I will be using Jackson again in the future, I hope. – JoshSnow Apr 18 '11 at 07:31

2 Answers2

1

You want to use org.codehaus.jackson.map.JsonDeserializer and write the custom deserialization code. Something like:

public class DateDeserializer extends JsonDeserializer<Long> {
    @Override
    public Long deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
       ... custom logic
    }
}

I guess you have to figure out when a Long property has to be deserialized to Date. Maybe using annotations on your pojos?

Luciano Fiandesio
  • 10,037
  • 10
  • 48
  • 56
  • thanks for your reply. I'll try this - although looking through the source code, I notice there's already a class named DateDeserializer. The answer may lie on the serializer side - maybe suppressing Timestamps or writing type information to the JSON String also. – JoshSnow Mar 31 '11 at 16:17
-1

I don't know if a String representation of the Date would be of any help?

If yes, then you could try setting the DateFormat on the ObjectMapper. The deserialization would then be in the readable String format.

E.g for the below code, the output would be like [{"birthDate":"March 30, 2011"}]

    @Test
public void testJsonConvertDate(){

    ObjectMapper mapper = new ObjectMapper();
    mapper.getSerializationConfig().setDateFormat(DateFormat.getDateInstance(DateFormat.LONG));
    StringWriter stringWriter = new StringWriter();
    try {
        mapper.writeValue(stringWriter, Arrays.asList(new TestUser(new Date())));
    }
    catch (IOException e) {
        e.printStackTrace();
    }

    System.out.println(stringWriter.toString());
}

private class TestUser {
    Date birthDate;

    private TestUser(Date birthDate) {
        this.birthDate = birthDate;
    }

    public Date getBirthDate() {
        return birthDate;
    }

    public void setBirthDate(Date birthDate) {
        this.birthDate = birthDate;
    }
}
Prasanna
  • 34
  • 2
  • Thanks for your reply. I don't think this gives me what I need. Maybe I wasn't clear, but basically I **serialize** (deflate) from a `java.util.Date` and I want the value to **deserialize** (inflate) back to a `java.util.Date`. By default, Jackson seems to serialize java.util.Date instances as Longs - which is okay - I just need it to deserialize back to an instance of `java.util.Date` rather than a `Long`. Your example deserializes the date to a `String` instance, not a `Date` instance. – JoshSnow Mar 31 '11 at 08:56
  • I bumped into the same issue and pretty much have determined that without a POJO acting as a guide for deserialized type, you're stuck. http://stackoverflow.com/questions/18796349/jackson-de-serializing-date-to-string-to-date-in-generic-maps – Buzz Moschetti Oct 10 '13 at 12:13