JAXB Custom Binding for Joda-Time

Java XMLI’m extensively using Joda-Time for handling time in my Java development, client or server side. Joda-Time is the codebase of the coming RI implementation of JSR-310 that will hopefully ship in Java 7.

I often need to work with dates in web services implementations, here is the JAXB custom binding lines I use to un/marshall JodaTime types to standard xs:date and xs:dateTime XML Schema types.

Note : I’m using the RI implementation of JAXB spec bundled in Metro.

DateTimeXmlAdapter that convert Joda-Time types to standard java types

import java.util.Date;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import org.joda.time.DateTime;

@XmlTransient
public class DateTimeXmlAdapter extends XmlAdapter {

    @Override
    public DateTime unmarshal(Date date) throws Exception {
        return new DateTime(date.getTime());
    }

    @Override
    public Date marshal(DateTime dateTime) throws Exception {
        return new Date(dateTime.getMillis());
    }

}

JAXB Custom binder for binding xs:date to java.util.Date.

In the documentation, an example JAXB customization file that use this binder.

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import javax.xml.bind.DatatypeConverter;

/**
 * <?xml version="1.0" encoding="UTF-8"?>
 * <bindings xmlns="http://java.sun.com/xml/ns/jaxb" 
 *           version="2.0" 
 *           xmlns:xs="http://www.w3.org/2001/XMLSchema">
 *     <globalBindings>
 *         <javaType name="java.util.Date" xmlType="xs:date"
 *                   parseMethod="org.your.package.name.XSDateCustomBinder.parseDate"
 *                   printMethod="org.your.package.name.XSDateCustomBinder.printDate"
 *         />
 *     </globalBindings>
 * </bindings>
 */
public class XSDateCustomBinder {

    public static Date parseDate(String s) {
        return DatatypeConverter.parseDate(s).getTime();
    }

    public static String printDate(Date dt) {
        Calendar cal = new GregorianCalendar();
        cal.setTime(dt);
        return DatatypeConverter.printDate(cal);
    }

}

JAXB Custom binder for binding xs:dateTime to java.util.Date.

In the documentation, an example JAXB customization file that use this binder.

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import javax.xml.bind.DatatypeConverter;

/**
 * <?xml version="1.0" encoding="UTF-8"?>
 * <bindings xmlns="http://java.sun.com/xml/ns/jaxb" 
 *           version="2.0" 
 *           xmlns:xs="http://www.w3.org/2001/XMLSchema">
 *     <globalBindings>
 *         <javaType name="java.util.Date" xmlType="xs:dateTime"
 *                   parseMethod="org.your.package.name.XSDateTimeCustomBinder.parseDateTime"
 *                   printMethod="org.your.package.name.XSDateTimeCustomBinder.printDateTime"
 *         />
 *     </globalBindings>
 * </bindings>
 */
public class XSDateTimeCustomBinder {

    public static Date parseDateTime(String s) {
        return DatatypeConverter.parseDate(s).getTime();
    }

    public static String printDateTime(Date dt) {
        Calendar cal = new GregorianCalendar();
        cal.setTime(dt);
        return DatatypeConverter.printDate(cal);
    }

}

I hope this may help you.

10 thoughts on “JAXB Custom Binding for Joda-Time

  1. Yes, your article is helpful indeed. It gave me a big jumpstart to do my own bindings for JAXB 2.0.5 fcs. Thanks.

    I did run into a few problems and have overcame them, as listed below.
    1. I had to insert another statement under the top-level , like this:
    .
    2. Jaxb/xjc generated for me a glue file: Adapter1.java for the bindings to work correctly:
    public class Adapter1 extends XmlAdapter

    And hey, thanks for introducing me to joda-time. Looks cool.

    –Tom

  2. From what I know the jaxb/jaxws maven plugin does not fit well in maven projects configuration and inheritance model (I even had issues binding multiples executions to the lifecycle).

    You could build an artifact containing XmlAdapters and JAXB customization xml files. Then add this artifact to projects dependencies and use the dependency plugin to unpack it in the build target directory. Last step would be to add the JAXB xml configuration files paths to the jaxb/jaxws maven plugin executions. Maybe by inheritance.

    I did not try this so I don’t know if it could work out of the box. If you encounter issues, I’m interested in reading from you.

  3. I’m trying to do this with jboss jax-ws, which generates wsdl from jaxb annotations. My problem is how to map joda LocalDate to xs:date type. I have added an adapter which converts between LocalDate and java.util.Date. I added the annotation @XmlJavaTypeAdapter
    The result is xs:dateTime.
    That is probably because java.util.Date is default mapped to xs:dateTime. How do I map it to xs:date?

  4. Answering my previous question:
    I created an adapter that converts between LocalDate and String and then I added the annotation @XmlSchemaType(name = “date”).

    public class JodaLocalDateXmlAdapter extends XmlAdapter {
    @Override
    public LocalDate unmarshal(String str) throws Exception {
    return new LocalDate(str);
    }

    @Override
    public String marshal(LocalDate localDate) throws Exception {
    // toString is in ISO8601 yyyy-MM-dd
    return localDate.toString();
    }
    }

    1. Hi Felipe, nice to see you reading around.

      I read your blog post on java.net and smth was telling me : “déjà vu” ;) Nice catch on the time zone issue.

      I’m working slowly on asadmin-maven-plugin. I still need it for GF2 and trunk is much more usefull than the last release already. I have not much time for it but I’ll be happy to open codebase access for contributions.

      /Paul

  5. There is a small bug in xs:dateTime to java.util.Date code. The lines “return DatatypeConverter.parseDate(s).getTime();” and “return DatatypeConverter.printDate(cal);” should use the DatatypeConverter methods parseDateTime and printDateTime to handle the time portion of the dateTime value.

    /James

Leave a comment