2012-07-17 9 views
35

Qual è la differenza tra l'annotazione di una classe con @XMLRootElement e @XMLType. Ho annotato le classi con @XMLType quando la struttura verrà utilizzata più di una volta all'interno di uno schema XML e con @XMLRootElement quando verrà utilizzata una sola volta: è questo l'approccio migliore?@XMLRootElement contro @XmlType

Una domanda diversa ma correlata che includerò qui. L'annotazione @XMLType ha un attributo propOrder per specificare in quale ordine vengono visualizzati i suoi elementi - esiste un equivalente per @XMLRootElement?

Sto usando queste annotazioni insieme alle annotazioni JAX-WS per creare servizi Web se questo fa alcuna differenza.

risposta

17

La differenza tra XmlRootElement e XmlType è una questione di ambito. Ricorda che questa annotazione sta semplicemente dettando la creazione dello schema utilizzato per generare il tuo XML. Il XmlRootElement indicato un elemento globale (con un tipo anonimo o schema):

<xs:element name=foo type="bar"> </xs:element> <-- schema type 

mentre il XmlType è usato per indicare un elemento locale (con un tipo anonimo o complessa):

<xs:complexType name=bar> </xs:complexType> <-- complex type 

il principale le differenze in locale/globale qui sono nella gerarchia dello schema in cui apparirà il tuo oggetto e se stai dichiarando un tipo di schema o un tipo complesso. La documentazione per entrambe queste annotazioni è ben scritto e comprende esempi:

XmlRootElement

XmlType

EDIT: Affrontare la questione propOrder: è possibile utilizzarlo su un elemento globale, se siete anche dichiarare un locale tipo:

@XmlRootElement (name="PersonElement") 
@XmlType (propOrder={"firstname", "lastname"}) 
public class People{ 
    @XmlElement 
    public String firstname; 
    public String lastname; 
} 

Questo produrrà qualcosa come:

<xs:element name="PersonElement" type="People"/> 
<xs:complexType name="People"> 
    <xs:sequence> 
     <xs:element name="firstname" type="xs:string"/> 
     <xs:element name="lastname" type="xs:string"/> 
    </xs:sequence> 
</xs:complexType> 
17

ho annotare le classi con @XMLType quando la struttura sarà utilizzato più di una volta all'interno di uno schema XML e con @XmlRootElement quando sarà usato solo una volta - è questo l'approccio migliore?

Una cosa da sapere è che non è richiesta l'annotazione @XmlRootElement o @XmlType. Non sono l'equivalente di @Entity di JPA. È possibile utilizzare un'implementazione JAXB (JSR-222) senza annotazioni cosa così mai:

Qui di seguito vi spiego cosa @XmlRootElement e @XmlType fanno.


@XmlRootElement

Ci sono momenti in cui l'implementazione JAXB ha bisogno di istanziare un oggetto basato solo sulla elemento XML che è in fase di elaborazione. L'annotazione @XmlRootElement è il mezzo principale per specificare questa associazione. Nota se una classe corrisponde a più di un elemento XML insteat allora l'annotazione @XmlElementDecl dovrebbe essere utilizzato,

RUOLO # 1 - Specifica l'oggetto principale

@XmlRootElement è principalmente utilizzato per specificare l'oggetto principale. Questo è così quando l'implementazione di JAXB inizia a smantellare un documento XML sa quale oggetto istanziare. Quasi tutte le annotazioni successive si baseranno sulle informazioni raccolte dalla classe genitore.

Foo

@XmlRootElement(name="root") 
public class Foo { 

    private String name; 

} 

Bar

public class Bar { 

    private String name; 

} 

XML

<root> 
    <name>Jane Doe</name> 
</root> 

Demo

Foo foo = (Foo) unmarshaller.unmarshal(xml); 
Bar bar = unmarshaller.unmarshal(xml, Bar.class).getValue(); 

RUOLO # 2 - Sostituzione Gruppi

I @XmlElementRef delegati di annotazione del tipo di oggetto istanziato al nome/uri dell'elemento. Ciò abilita la mappatura al concetto di gruppi di sostituzione per rappresentare l'ereditarietà.

RUOLO # 3 - Tutti i Contenuti

@XmlAnyElement consente di mappare una sezione wild card del documento XML. Se si specifica @XmlAnyElement(lax=true), gli elementi associati agli oggetti dominio verranno convertiti nell'oggetto dominio corrispondente.


@XmlType

RUOLO # 1 - Schema Gen

Per impostazione predefinita un tipo complesso di nome viene generato per ogni classe Java noto al Contesto JAXB. È possibile controllare il nome di questo tipo utilizzando l'annotazione @XmlType o specificare che un tipo complesso anonimo debba essere generato specificando il nome come "".

RUOLO # 2 - Trasmissione e xsi: type

Per impostazione predefinita JAXB sfrutta l'attributo xsi:type come indicatore eredità. Il valore su questo attributo corrisponde al nome e allo spazio dei nomi che hai specificato nell'annotazione @XmlType o è predefinito in base alla classe.

RUOLO # 3 - Prop Order

Come si menziona è possibile utilizzare il @XmlType per specificare l'ordine di proprietà.

RUOLO # 4 - Metodi di fabbrica

@XmlType consente di specificare una classe di fabbrica e/o un metodo che può essere utilizzato per creare un'istanza dell'oggetto dominio invece del default costruttore.


Una questione diversa ma collegata, che io includo qui. L'annotazione @XMLType ha un attributo propOrder per specificare in quale ordine sono visualizzati gli elementi - esiste un equivalente per @XMLRootElement?

No, l'aspetto propOrder appartiene all'annotazione @XmlType. Questo ha senso poiché i tipi complessi sono responsabili della specificazione di un ordine (o mancanza). Ovviamente puoi usare queste annotazioni contemporaneamente.

@XmlRootElement 
@XmlType(propOrder={"foo", "bar"} 
public class Root { 
    ... 
}