Customized date format in JAXB

Nowadays, it is very common to work with JAXB to help us to marshal and unmarshal objects into XML or XML into objects. These objects can be simple object or objects created by us if we use the correct annotations. It is clear that JAXB is very useful but, sometimes, it is not enough with the default values the API is offering us.

Recently, we had a problem with the date format. The external system where we were trying to send information was expecting a very concrete pattern for the date objects in the XML, and the default format JAXB was offering us was not correct. After test a couple of solutions, we find one that it was working very good and it was quite simple to implement.

The idea was to rewrite the adapter with the desired format and after that, using the correct annotation, tell JAXB be the correct format. Easier than it sounds.

The first step is to write our adapter object extending the object XmlAdapter. In there, we can define the exact format we want to use when the marshalling operation is performed.

package com.wordpress.binarycoders.services.jaxb.utils;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;

import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

public class DateAdapter extends XmlAdapter<String, XMLGregorianCalendar> {

    private DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

    @Override
    public String marshal(XMLGregorianCalendar v) throws Exception {
        Calendar calendar = v.toGregorianCalendar();
        
        return dateFormat.format(calendar.getTime());
    }

    @Override
    public XMLGregorianCalendar unmarshal(String v) throws Exception {
        
        GregorianCalendar c = new GregorianCalendar();
        c.setTime(dateFormat.parse(v));
        
        return  DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
    }

}

This example is using a XMLGregorianCalendar object, but this can be done with any date object.

The second step, it is to indicate JAXB that this adapter should be used instead of the default one. We do this with the annotation @XmlJavaTypeAdapter. Something like this:

@XmlSchemaType(name = "date")
@XmlJavaTypeAdapter(DateAdapter.class)
protected XMLGregorianCalendar date;

That´s all. Now, when the marshaling operation is performed, we should obtain the desired date format in our XMLs.

See you.

Advertisements
Customized date format in JAXB