2010-07-01 9 views
5

Estoy usando JAXB para ordenar una clase que tiene una variable de instancia declarada como clase Foo. En el tiempo de ejecución, esa variable de instancia se establece en una instancia de una subclase de Foo, digamos FooBar. Hay anotaciones JAXB básicas tanto en la clase Foo como en FooBar.Clasificación JAXB declarada clase primaria vs. subclase de tiempo de ejecución real

La salida XML muestra que una instancia de Foo se está calculando en lugar de FooBar. ¿Hay algo específico que tengo que hacer en términos de anotaciones para decirle a JAXB cómo organizar correctamente la subclase de tiempo de ejecución en lugar de la superclase declarada?

Probé un experimento en el que clasifiqué directamente una variable de instancia foo del tipo Foo que se estableció en una instancia de FooBar en tiempo de ejecución. Corregió correctamente una instancia de FooBar.

Esto es claramente diferente de ordenar una clase que contiene una variable de instancia de tipo Foo porque la llamada de Marshal se hace en la clase contenedora y JAXB simplemente clasifica esos campos de clases (estoy usando @XmlAccessorType (XmlAccessType.FIELD) anotación).

Mi expectativa era que JAXB podría inspeccionar correctamente el tipo de tiempo de ejecución de la variable de instancia, pero quizás ese no sea el caso. ¿Esta situación requiere el uso de una implementación de XmlAdapter como se describe aquí?

JAXB inheritance, unmarshal to subclass of marshaled class

Gracias,

Chris

Respuesta

7

Voy a utilizar estas clases como un ejemplo:

@XmlRootElement 
class Foo { public Bar bar; } 
class Bar {} 
class Baz extends Bar {} 
class Quux extends Bar {} 

Bueno, parece que hay dos soluciones posibles:

Puede decirle a JAXB sobre todas las clases involucradas (incl uding subclases) en el momento de creación del contexto.

JAXBContext.newInstance(Foo.class, Bar.class, Baz.class, Quux.class); 

te dicen JAXB sobre las otras clases a través de la @XmlSeeAlso anotación.

@XmlRootElement 
@XmlSeeAlso({Baz.class, Quux.class}) 
class Foo { public Bar bar; } 

Si Mariscal como esto

Foo f = new Foo(); 
f.bar = new Baz(); 

m.marshal(f, System.err); 

que reciben

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<foo> 
    <bar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="baz"/> 
</foo> 

No es hermosa pero el tipo de información se conserva.

Cuestiones relacionadas