JAXB Custom Binding – Java.util.Date / Spring 3 Serialization

June 7, 2011 | By

111 jaxb JAXB Custom Binding   Java.util.Date / Spring 3 SerializationJaxB can handle Java.util.Date serialization, but it expects the following format: “yyyy-MM-ddTHH:mm:ss“. What if you need to format the date object in another format?

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! icon smile JAXB Custom Binding   Java.util.Date / Spring 3 Serialization

Filed in: Spring | Tags: , , , , ,

Comments (9)

  1. Hi Loiane,

    Great post. Another thing you can do when you want to control the format of Date objects with JAXB is leverage the @XmlSchemaType annotation, and do something like @XmlSchemaType(name = “date”).

    For more information see:
    http://bdoughan.blogspot.com/2011/01/jaxb-and-datetime-properties.html

    -Blaise

  2. Eric Jablow

    What business need requires you to serialize in this way? I suppose you aren’t using the XML file only for computer-to-computer data exchange. If you want to consider only a calendar date, perhaps you should consider using the Joda-Time date classes, together with a similar custom serializer.

  3. BenC

    Be careful with SimpleDateFormat, it’s not thread-safe. It’s really easy to switch to using JodaTime for your formatting needs. I have a very similar XmlAdapter class that uses it:
    public class TimestampAdapter extends XmlAdapter {
    private final static DateTimeFormatter TIMESTAMPFORMATTER = DateTimeFormat.forPattern(“MM/dd/yyyy HH:mm:ss:SSS”);
    @Override
    public String marshal(Date d) throws Exception {
    return TIMESTAMPFORMATTER.print(d.getTime());
    }

    @Override
    public Date unmarshal(String d) throws Exception {
    return TIMESTAMPFORMATTER.parseDateTime(d)).toDate();
    }
    }

  4. By the way you can use Jackson JSON Processor’s ‘JsonConfig’ option to overcome this issue. JsonConfig class offers to registering json value processing by the class you want. For example in this case you can define DateJsonValueProcesser by implementing JsonValueProcessor. Then you can register it with the class you want. (i.e. java.util.Date.class)

  5. Mike

    Quite stupid, one should never change the serialization format of dates to something other than ISO8601.

  6. BiGF00T

    I guess there might be reasons to use a different time format if the reader of the xml expects it this way. Anyway, this is a nice little example of how to use an XmlAdapter. And this is how I came to this page. Took me 5 minutes to understand and implement my own XmlAdapter after reading this.

    Thanks Loiane.