Date format Mapping to JSON Jackson Date format Mapping to JSON Jackson json json

Date format Mapping to JSON Jackson

Since Jackson v2.0, you can use @JsonFormat annotation directly on Object members;

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm a z")private Date date;

What is the formatting I need to use to carry out conversion with Jackson? Is Date a good field type for this?

Date is a fine field type for this. You can make the JSON parse-able pretty easily by using ObjectMapper.setDateFormat:

DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm a z");myObjectMapper.setDateFormat(df);

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.

Yes. You have a few options, including implementing a custom JsonDeserializer, e.g. extending JsonDeserializer<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):

@JsonFormat(locale = "hu", shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm", timezone = "CET")@JsonFormat(locale = "hu", shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm", timezone = "Europe/Budapest")

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

There are examples for Date fields but I needed for Calendar fields so here is my implementation:

The serializer class:

public class CustomCalendarSerializer extends JsonSerializer<Calendar> {    public static final SimpleDateFormat FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm");    public static final Locale LOCALE_HUNGARIAN = new Locale("hu", "HU");    public static final TimeZone LOCAL_TIME_ZONE = TimeZone.getTimeZone("Europe/Budapest");    @Override    public void serialize(Calendar value, JsonGenerator gen, SerializerProvider arg2)            throws IOException, JsonProcessingException {        if (value == null) {            gen.writeNull();        } else {            gen.writeString(FORMATTER.format(value.getTime()));        }    }}

The deserializer class:

public class CustomCalendarDeserializer extends JsonDeserializer<Calendar> {    @Override    public Calendar deserialize(JsonParser jsonparser, DeserializationContext context)            throws IOException, JsonProcessingException {        String dateAsString = jsonparser.getText();        try {            Date date = CustomCalendarSerializer.FORMATTER.parse(dateAsString);            Calendar calendar = Calendar.getInstance(                CustomCalendarSerializer.LOCAL_TIME_ZONE,                 CustomCalendarSerializer.LOCALE_HUNGARIAN            );            calendar.setTime(date);            return calendar;        } catch (ParseException e) {            throw new RuntimeException(e);        }    }}

and the usage of the above classes:

public class CalendarEntry {    @JsonSerialize(using = CustomCalendarSerializer.class)    @JsonDeserialize(using = CustomCalendarDeserializer.class)    private Calendar calendar;    // ... additional things ...}

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).