2010-07-01 12 views
5

Sto utilizzando JAXB per eseguire il marshalling di una classe che ha una variabile di istanza dichiarata come classe Foo. In fase di runtime quella variabile di istanza è impostata su un'istanza di una sottoclasse di Foo, diciamo FooBar. Ci sono annotazioni JAXB di base su entrambe le classi Foo e FooBar.Il marshalling JAXB ha dichiarato classe secondaria rispetto alla sottoclasse runtime effettiva

L'output XML mostra che un'istanza di Foo sta eseguendo il marshalling anziché FooBar. C'è qualcosa di specifico che devo fare in termini di annotazioni per dire a JAXB come eseguire correttamente il marshalling della sottoclasse di runtime al posto della superclasse dichiarata?

Ho provato un esperimento in cui ho eseguito il marshalling diretto di una variabile di istanza foo di tipo Foo impostata su un'istanza di FooBar in fase di esecuzione. Ha eseguito correttamente il marshalling di un'istanza di FooBar.

Questo è chiaramente diverso dal marshalling di una classe che contiene una variabile di istanza di tipo Foo perché la chiamata al maresciallo viene effettuata sulla classe contenente e JAXB esegue il marshalling di quei campi di classi (sto usando il @XmlAccessorType (XmlAccessType.FIELD) annotazione).

La mia aspettativa era che JAXB potesse ispezionare correttamente il tipo di runtime della variabile di istanza, ma forse non è così. Questa situazione richiede l'utilizzo di un'implementazione di XmlAdapter come descritto qui?

JAXB inheritance, unmarshal to subclass of marshaled class

Grazie,

Chris

risposta

7

Userò queste classi come esempio:

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

Beh, sembra che ci siano due possibili soluzioni:

Puoi dire a JAXB di tutte le classi coinvolte (incl uding sottoclassi) al momento della creazione del contesto.

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

vi dica JAXB sulle altre classi tramite il @XmlSeeAlso annotazione.

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

Se si effettua il marshalling come questo

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

m.marshal(f, System.err); 

ricevi

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

Non è bello, ma digitare le informazioni è conservato.

Problemi correlati