No parece ser un requisito de que el paquete que está siendo anotado tener nada que ver con el paquete de los tipos no pueden vincularse ser adaptados. Eso es conveniente y agradable.
Esto es correcto. Cuando se usa @XmlJavaTypeAdapter
en el nivel de paquete, significa aplicar este adaptador a todas las propiedades del tipo especificado para las clases que residen en este paquete. Lo demostraré a continuación con un ejemplo.
forum8735737.bar.package-info
Para este paquete especificaremos un XmlAdapter
que se aplicará a todos los campos/propiedades de tipo String
dentro de este paquete.
@XmlJavaTypeAdapters({
@XmlJavaTypeAdapter(value=StringAdapter.class, type=String.class)
})
package forum8735737.bar;
import javax.xml.bind.annotation.adapters.*;
forum8735737.bar.StringAdapter
Nuestra XmlAdapter
simplemente convertir todas las instancias de String
a mayúsculas cuando cálculo de referencias:
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
representa un POJO en este paquete con una propiedad de tipo 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 representa un objeto de dominio con una propiedad de tipo String
que existe en un paquete diferente. El XmlAdapter
se registró para el paquete forum8735737.bar
no serán aplicables a esta clase:
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;
}
}
demostración
el siguiente código creará instancias de ambos Foo
y Bar
y reunir a 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);
}
}
Salida
Aviso cómo el valor del elemento name
dentro bar
se ha convertido en mayúsculas:
<?xml version="1.0" encoding="UTF-8"?>
<foo>
<name>Foo</name>
</foo>
<?xml version="1.0" encoding="UTF-8"?>
<bar>
<name>BAR</name>
</bar>
muy útil; Gracias. ¿Se camina el gráfico desde allí? Es decir, supongamos que tengo un único tipo vinculable que alimentar a JAXB. Supongamos además que su paquete está anotado con 647 anotaciones 'XmlJavaTypeAdapter', cada una de las cuales especifica un tipo no enlazable y un adaptador para ese tipo. ¿Mi 'JAXBContext' ahora podría manejar los 647 tipos ahora adaptados? –
@ Laird: Sí, siempre que (a) tenga la RAM para manejarlo, y (b) Todos los tipos vinculables estén en ese paquete. – skaffman
Interesante. Sin embargo, parece extraño que tuviera que arrancar todo el proceso. Quiero decir, si puedo configurar una pila de adaptadores simplemente alimentando JAXB con un solo tipo, entonces espero que sea posible mejorar JAXB para que ese tipo único no sea necesario tampoco. Al igual, haz que JAXB mire de forma predeterminada un "paquete" 'package-info' en algún lugar para que el arranque inicial no sea necesario. De nuevo, gracias por tu ayuda. –