7

I want to change "javax.xml.datatype.XMLGregorianCalendar" to "java.util.Date" when unmarshalling from xml to Java class of JAXB.

But I don't put any annotations of @XmlJavaTypeAdapter in Java classes.

So, I'm going to try to use an annotation of @XmlJavaTypeAdapters, but I don't know how to use it...

Please show me examples for using it.

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
Take
  • 213
  • 1
  • 6
  • 12
  • 1
    Are you using code generated from a schema, or hand-written JAXB bindings? – skaffman Jan 12 '11 at 10:27
  • Thank you for your reply, skaffman. I made it hand-written, and the schema is created from JavaBeans with no annotaions for using Ant task. – Take Jan 13 '11 at 00:06

1 Answers1

11

As an interesting aside, you don't actually need to adapt XMLGregorianCalendar to Date, since JAXB supports java.util.Date natively -- like this:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class Example {
    @XmlSchemaType(name = "date")
    public Date publishingDate;
}

If you need it, @XmlJavaTypeAdapter can work like this, assuming your custom class:

public class SillyDate {
    public SillyDate(int year, int month, int day) {
        super();
        this.year = year;
        this.month = month;
        this.day = day;
    }

    public String toString() {
      return "SillyDate [year=" + year + ", month=" + month + ", day=" + day + "]";
    }

    public int year;
    public int month;
    public int day;
}

You need a class which JAXB can understand, and then write an adapter between that class and the custom class, like this:

public class SillyDateAdapter extends XmlAdapter<XMLGregorianCalendar, SillyDate> {
    public SillyDate unmarshal(XMLGregorianCalendar val) throws Exception {
      return new SillyDate(val.getYear(), val.getMonth(), val.getDay());
    }

    public XMLGregorianCalendar marshal(SillyDate val) throws Exception {
      return DatatypeFactory.newInstance().newXMLGregorianCalendarDate(val.year, val.month, val.day, 0);
    }
}

Now you can use that in your own classes, like this:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class Example2 {
    @XmlSchemaType(name = "date")
    @XmlJavaTypeAdapter(type=XMLGregorianCalendar.class,value =SillyDateAdapter.class)
    public SillyDate publishingDate;
}

There are plenty of good examples of using the @XmlJavaTypeAdapter available on the net, like this one and this one, and several others. Happy adapting!

JesperSM
  • 1,418
  • 1
  • 11
  • 15
  • Thank you JesperSM ! I'm going to use the @XmlJavaTypeAdapter annotation in package-info.java. But next, I don't know how to use package-info.java in Java. I use Ant task for compiling Java classes, is the package-info.java excluded it ? – Take Jan 13 '11 at 11:02
  • 1
    You just put a file called package-info.java in the package, and it will be picked up. For comparison, run a simple schema through 'xjc' and see what it produces. If you are pleased with answer, don't forget to mark it as accepted. – JesperSM Jan 13 '11 at 13:18
  • Check out my answer to another question for an example using package-info.java: http://stackoverflow.com/questions/4687188/how-to-convert-dateactionscript-3-to-java-util-date-through-a-xml/4694496#4694496 – bdoughan Jan 17 '11 at 15:01