JAXB Custom Binding – Java.util.Date / Spring 3 Serialization
I had the same issue when I was working with Spring MVc 3 and Jackson JSON Processor, and recently, I faced the same issue working with Spring MVC 3 and JAXB for XML serialization.
Let’s digg into the issue:
Problem:
I have the following Java Beans which I want to serialize in XML using Spring MVC 3:
package com.loiane.model; import java.util.Date; public class Company { private int id; private String company; private double price; private double change; private double pctChange; private Date lastChange; //getters and setters
And I have another object which is going to wrap the POJO above:
package com.loiane.model; import java.util.List; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name="companies") public class Companies { @XmlElement(required = true) private List<Company> list; public void setList(List<Company> list) { this.list = list; } }
In my Spring controller, I’m going to return a List of Company through the the @ResponseBody annotation – which is going to serialize the object automatically with JaxB:
@RequestMapping(value="/company/view.action") public @ResponseBody Companies view() throws Exception {}
When I call the controller method, this is what it returns to the view:
<companies> <list> <change>0.02</change> <company>3m Co</company> <id>1</id> <lastChange>2011-09-01T00:00:00-03:00</lastChange> <pctChange>0.03</pctChange> <price>71.72</price> </list> <list> <change>0.42</change> <company>Alcoa Inc</company> <id>2</id> <lastChange>2011-09-01T00:00:00-03:00</lastChange> <pctChange>1.47</pctChange> <price>29.01</price> </list> </companies>
Note the date format. It is not the format I expect it to return. I need to serialize the date in the following format: “MM-dd-yyyy“ Solution:
I need to create a class extending the XmlAdapter and override the marshal and unmarshal methods and in these methods I am going to format the date as I need to:
package com.loiane.util; import java.text.SimpleDateFormat; import java.util.Date; import javax.xml.bind.annotation.adapters.XmlAdapter; public class JaxbDateSerializer extends XmlAdapter<String, Date>{ private SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy"); @Override public String marshal(Date date) throws Exception { return dateFormat.format(date); } @Override public Date unmarshal(String date) throws Exception { return dateFormat.parse(date); } }
And in my Java Bean class, I simply need to add the @XmlJavaTypeAdapter annotation in the get method of the date property.
package com.loiane.model; import java.util.Date; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import com.loiane.util.JaxbDateSerializer; public class Company { private int id; private String company; private double price; private double change; private double pctChange; private Date lastChange; @XmlJavaTypeAdapter(JaxbDateSerializer.class) public Date getLastChange() { return lastChange; } //getters and setters }
If we try to call the controller method again, it is going to return the following XML:
<companies> <list> <change>0.02</change> <company>3m Co</company> <id>1</id> <lastChange>09-01-2011</lastChange> <pctChange>0.03</pctChange> <price>71.72</price> </list> <list> <change>0.42</change> <company>Alcoa Inc</company> <id>2</id> <lastChange>09-01-2011</lastChange> <pctChange>1.47</pctChange> <price>29.01</price> </list> </companies>
Problem solved!
Happy Coding!
Reference: JAXB Custom Binding – Java.util.Date / Spring 3 Serialization from our JCG partner Loiane Groner at the Loiane Groner’s blog blog.