There does not appear to be a requirement that the package that is
being annotated have anything to do with the package of the
non-bindable types being adapted. That is convenient and nice.
This is correct. When @XmlJavaTypeAdapter
is used at the package level it means apply this adapter to all properties of the specified type for classes that reside in this package. I'll demonstrate below with an example.
forum8735737.bar.package-info
For this package we will specify an XmlAdapter
that will be applied to all fields/properties of type String
within this package.
@XmlJavaTypeAdapters({
@XmlJavaTypeAdapter(value=StringAdapter.class, type=String.class)
})
package forum8735737.bar;
import javax.xml.bind.annotation.adapters.*;
forum8735737.bar.StringAdapter
Our XmlAdapter
will simply convert all instances of String
to upper case when marshalling:
package forum8735737.bar;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class StringAdapter extends XmlAdapter<String, String> {
@Override
public String unmarshal(String v) throws Exception {
return v;
}
@Override
public String marshal(String v) throws Exception {
if(null == v) {
return v;
}
return v.toUpperCase();
}
}
forum8735737.bar.Bar
Bar
represents a POJO in this package with a property of type String
:
package forum8735737.bar;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Bar {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
forum8735737.foo.Foo
Foo represents a domain object with a property of type String
that exists in a different package. The XmlAdapter
we registered for the forum8735737.bar
package will not apply to this class:
package forum8735737.foo;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Foo {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Demo
The following code will create instances of both Foo
and Bar
and marshal them to XML:
package forum8735737;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import forum8735737.bar.Bar;
import forum8735737.foo.Foo;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Foo.class, Bar.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
Foo foo = new Foo();
foo.setName("Foo");
marshaller.marshal(foo, System.out);
Bar bar = new Bar();
bar.setName("Bar");
marshaller.marshal(bar, System.out);
}
}
Output
Notice how the value of the name
element within bar
has been converted to upper case:
<?xml version="1.0" encoding="UTF-8"?>
<foo>
<name>Foo</name>
</foo>
<?xml version="1.0" encoding="UTF-8"?>
<bar>
<name>BAR</name>
</bar>