eskatos's thoughts

JAXB Custom Binding for Joda-Time

with 10 comments

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.

About these ads

Written by Paul

November 24, 2007 at 4:16 pm

Posted in Code

Tagged with , , , ,

10 Responses

Subscribe to comments with RSS.

  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

    Tom Truong

    December 7, 2007 at 4:52 am

  2. Thanks.
    Do you know how can i have this binding global for all schemas? (i use maven plugin)

    Avihai

    December 25, 2008 at 5:08 pm

  3. 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.

    eskatos

    December 27, 2008 at 8:11 pm

  4. 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?

    Patrik

    October 30, 2009 at 2:22 pm

  5. 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();
    }
    }

    Patrik

    October 30, 2009 at 3:15 pm

  6. I wrote another entry inspired din your original content. My problem was slightly different but the the solution followed the same principle, I just adapted your code:

    http://weblogs.java.net/blog/felipegaucho/archive/2009/12/06/jaxb-customization-xsddatetime

    Thanks for the good blog …

    * and keep working on the asadmin maven plugin, we missed that a lot :)

    Felipe Gaúcho

    December 8, 2009 at 11:25 am

    • 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

      eskatos

      December 8, 2009 at 1:24 pm

  7. 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

    James

    June 24, 2010 at 1:49 am


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: