Did you know? DZone has great portals for Python, Cloud, NoSQL, and HTML5!

Loiane Groner, Brazilian, works as a Java Developer/IT Specialist/Systems Analyst at IBM Brazil on an international account. She has 4+ years of experience in developing JEE applications. She is the ESJUG (Espirito Santo Java Users Group) and CampinasJUG (Campinas Java Users Group) leader and coordinator. Loiane is passionate about technology and programming. Loiane is a DZone MVB and is not an employee of DZone and has posted 35 posts at DZone. You can read more from them at their website. View Full User Profile

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

06.07.2011
Email
Views: 4707
  • submit to reddit

JaxB 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 dig 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! :)

 

From http://loianegroner.com/2011/06/jaxb-custom-binding-java-util-date-spring-3-serialization/

Published at DZone with permission of Loiane Groner, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Blaise Doughan replied on Wed, 2011/06/08 - 9:24am

You can also use @XmlSchemaType to control the representation of java.util.Date properties in JAXB:

@XmlSchemaType(name="date")
public Date getLastChange() {
    return lastChange;
}

For more information see:

Jim van Dam replied on Thu, 2011/07/28 - 4:49am

If I use @XmlSchemaType with @XmlJavaTypeAdapter at the property/method level I get want I want in a schemagen generated xsd (xsd:date with my own string marshalling), but if I do the same thing at the packagelevel the @XmlSchemaType is ignored and the xsd shows xsd:string as the type (derived from the xmljavatypeadapter I presume).

If I remove the XmlJavaTypeAdapters at the package level and leave the XmlSchemaTypes then the right xsd types are generated.

Is this according to spec or am I missing something?

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.