I have a Date format coming from API like this:
"start_time": "2015-10-1 3:00 PM GMT+1:00"
Which is YYYY-DD-MM HH:MM am/pm GMT timestamp. I am mapping this value to a Date variable in POJO. Obviously, its showing conversion error.
I would like to know 2 things:
- What is the formatting I need to use to carry out conversion with Jackson? Is Date a good field type for this?
- In general, is there a way to process the variables before they get mapped to Object members by Jackson? Something like, changing the format, calculations, etc.
If anyone has problems with using a custom dateformat for java.sql.Date, this is the simplest solution:
(This SO-answer saved me a lot of trouble: https://stackoverflow.com/a/35212795/3149048 )
Jackson uses the SqlDateSerializer by default for java.sql.Date, but currently, this serializer doesn't take the dateformat into account, see this issue: https://github.com/FasterXML/jackson-databind/issues/1407 . The workaround is to register a different serializer for java.sql.Date as shown in the code example.
Date
is a fine field type for this. You can make the JSON parse-able pretty easily by usingObjectMapper.setDateFormat
:Yes. You have a few options, including implementing a custom
JsonDeserializer
, e.g. extendingJsonDeserializer<Date>
. This is a good start.Of course there is an automated way called serialization and deserialization and you can define it with specific annotations (@JsonSerialize,@JsonDeserialize) as mentioned by pb2q as well.
You can use both java.util.Date and java.util.Calendar ... and probably JodaTime as well.
The @JsonFormat annotations not worked for me as I wanted (it has adjusted the timezone to different value) during deserialization (the serialization worked perfect):
You need to use custom serializer and custom deserializer instead of the @JsonFormat annotation if you want predicted result. I have found real good tutorial and solution here http://www.baeldung.com/jackson-serialize-dates
There are examples for Date fields but I needed for Calendar fields so here is my implementation:
The serializer class:
The deserializer class:
and the usage of the above classes:
Using this implementation the execution of the serialization and deserialization process consecutively results the origin value.
Only using the @JsonFormat annotation the deserialization gives different result I think because of the library internal timezone default setup what you can not change with annotation parameters (that was my experience with Jackson library 2.5.3 and 2.6.3 version as well).
Building on @miklov-kriven's very helpful answer, I hope these two additional points of consideration prove helpful to someone:
(1) I find it a nice idea to include serializer and de-serializer as static inner classes in the same class. NB, using ThreadLocal for thread safety of SimpleDateFormat.
(2) As an alternative to using @JsonSerialize and @JsonDeserialize annotations on each individual class member you could also consider overriding Jackson's default serialization by applying the custom serialization at an application level, that is all class members of type Date will be serialized by Jackson using this custom serialization without explicit annotation on each field. If you are using Spring Boot for example one way to do this would as follows:
Just a complete example for spring boot application with
RFC3339
datetime formatSince Jackson v2.0, you can use @JsonFormat annotation directly on Object members;