Feb 10, 2012
Date formatting in JSON output – Spring 3 & Jackson
Among the list of enhancements in Spring 3 the most I like is some excellent support of JSON/Ajax, very simplified configuration of Spring MVC using mvc namespace & annotations.
One of them is @JsonSerialize annotation. The former is used to tell Spring what to use as sensible defaults based on entries in classpath, so if Jackson jars are in classpath, Jackson JSON Processor will be used to read/write JSON.
Whereas @JsonSerialize annotation can be used to override the default formatting strategy uses by Jackson during json serialization. This can be very handy when one is dealing with date time fields, lets take an example – I have a controller ‘subscription’ with an action name ‘getSubscriber(String subcriberId)’ and it returns an object of subscriber class as shown below:
//Controller - SubscriptionController.java
@Controller
@RequestMapping("/subsciption")
public class SubscriptionController {
@RequestMapping(value = "/getSubcriber", method = RequestMethod.GET)
public @ResponseBody
Subscriber getSubscriber(@RequestParam String subscriberId) {
return subscriberRepo.getSubscriber(subscriberId);
}
}
//Subscriber POJO - Subscriber.java
public class Subscriber {
private String subscriberId;
private Date subscriptionExpiryDate;
public Subscriber() { }
public String getSubscriberId() {
return this.subscriberId;
}
public void setSubscriberId(String subscriberId) {
this.subscriberId = subscriberId;
}
public Date getSubscriptionExpiryDate() {
return this.subscriptionExpiryDate;
}
public void setSubscriptionExpiryDate(Date subscriptionExpiryDate) {
this.subscriptionExpiryDate = subscriptionExpiryDate;
}
}
By default the serialized json output to this action will be:
{"subscriberId":"UFCC09211","subscriptionExpiryDate":1328866365808}
Notice the value of subscriptionExpiryDate field – it doesn’t look like a date or time, also what if one wants date time in particular format like yyyy-mm-dd? This is where @JsonSerialize comes in a picture. In order to override the default date formatting one has to extend JsonSerializer class provided by Jackson and override the serialize(Date value, JsonGenerator gen, SerializerProvider prov) method.
For our example CustomDateSerializer class looks like this:
public class CustomDateSerializer extends JsonSerializer<Date> {
@Override
public void serialize(Date value, JsonGenerator gen, SerializerProvider prov)
throws IOException, JsonProcessingException {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
String formattedDate = formatter.format(value);
gen.writeString(formattedDate);
}
}
and to tell Jackson to use this class to format date while serializing is to use the @JsonSerialize on get method of date field like this:
@JsonSerialize(using = CustomDateSerializer.class)
public Date getSubscriptionExpiryDate() {
return this.subscriptionExpiryDate;
}
that’s it, the output date will now be in ‘yyyy-mm-dd’ format:
{"subscriberId":"UFCC09211","subscriptionExpiryDate":"2012-02-10"}

Excellent, tnks… What about the input format??