web-dev-qa-db-fra.com

@XMLRootElement vs @XmlType

Quelle est la différence entre annoter une classe avec @XMLRootElement et @XMLType. J'ai annoté des cours avec @XMLType lorsque la structure sera utilisée plusieurs fois dans un schéma XML et avec @XMLRootElement quand il ne sera utilisé qu'une seule fois - est-ce la meilleure approche?

Une question différente mais connexe que je vais inclure ici. Le @XMLType l'annotation a un attribut propOrder pour spécifier dans quel ordre ses éléments apparaissent - existe-t-il un équivalent pour @XMLRootElement?

J'utilise ces annotations conjointement avec les annotations JAX-WS pour créer des services Web si cela fait une différence.

37
CodeClimber

La différence entre XmlRootElement et XmlType est une question de portée. N'oubliez pas que cette annotation ne fait que dicter la création du schéma utilisé pour générer votre XML. XmlRootElement désigne un élément global (avec un type anonyme ou de schéma):

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

tandis que XmlType est utilisé pour désigner un élément local (avec un type anonyme ou complexe):

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

Les principales différences locales/globales sont ici dans la hiérarchie du schéma dans lequel votre objet apparaîtra et si vous déclarez un type de schéma ou un type complexe. La documentation de ces deux annotations est bien écrite et comprend des exemples:

XmlRootElement

XmlType

EDIT: Répondre à la question propOrder: vous pouvez l'utiliser sur un élément global si vous déclarez également un type local:

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

Cela produira quelque chose comme:

<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>
21
DocWatson

J'ai annoté des classes avec @XMLType lorsque la structure sera utilisée plusieurs fois dans un schéma XML et avec @XMLRootElement lorsqu'elle ne sera utilisée qu'une seule fois - est-ce la meilleure approche?

Une chose à savoir est que ni l'annotation @XmlRootElement Ou @XmlType N'est requise. Ils ne sont pas l'équivalent de @Entity De JPA. Vous pouvez utiliser une implémentation JAXB (JSR-222) sans aucune annotation.

Ci-dessous, je vais expliquer ce que @XmlRootElement Et @XmlType Font.


@XmlRootElement

Il arrive que votre implémentation JAXB doive instancier un objet basé uniquement sur l'élément XML en cours de traitement. L'annotation @XmlRootElement Est le principal moyen de spécifier cette association. Notez que si une classe correspond à plusieurs éléments XML, l'annotation @XmlElementDecl Doit être utilisée insteat,

RÔLE # 1 - Spécification de l'objet racine

@XmlRootElement Est principalement utilisé pour spécifier l'objet racine. Il en est ainsi lorsque votre implémentation JAXB commence à démasquer un document XML, elle sait quel objet instancier. Presque toutes les annotations ultérieures seront basées sur des informations recueillies auprès de la classe parente.

Foo

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

    private String name;

}

Bar

public class Bar {

    private String name;

}

[~ # ~] xml [~ # ~]

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

Démo

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

RÔLE # 2 - Groupes de substitution

L'annotation @XmlElementRef Délègue le type d'objet instancié au nom/uri de l'élément. Cela permet la mise en correspondance avec le concept de groupes de substitution pour représenter l'héritage.

RÔLE # 3 - Tout contenu

@XmlAnyElement Vous permet de mapper une section générique de votre document XML. Si vous spécifiez @XmlAnyElement(lax=true), les éléments associés aux objets de domaine seront convertis en l'objet de domaine correspondant.


@XmlType

RÔLE # 1 - Génération de schéma

Par défaut, un type complexe nommé est généré pour chaque classe Java connue du contexte JAXB. Vous pouvez contrôler le nom de ce type à l'aide de l'annotation @XmlType Ou spécifier qu'un anonyme le type complexe doit être généré en spécifiant le nom comme "".

RÔLE # 2 - Héritage et xsi: type

Par défaut, JAXB utilise l'attribut xsi:type Comme indicateur d'héritage. La valeur de cet attribut correspond au nom et à l'espace de noms que vous avez spécifiés dans l'annotation @XmlType, Ou est définie par défaut en fonction de la classe.

RÔLE # 3 - Ordre des accessoires

Comme vous le mentionnez, vous pouvez utiliser le @XmlType Pour spécifier l'ordre des propriétés.

RÔLE # 4 - Méthodes d'usine

@XmlType Vous permet de spécifier une classe d'usine et/ou une méthode qui peut être utilisée pour instancier l'objet domaine au lieu du constructeur par défaut.


Une question différente mais connexe que je vais inclure ici. L'annotation @XMLType a un attribut propOrder pour spécifier l'ordre dans lequel ses éléments apparaissent - existe-t-il un équivalent pour @XMLRootElement?

Non, l'aspect propOrder appartient à l'annotation @XmlType. Cela est logique car les types complexes sont responsables de la spécification d'un ordre (ou d'un manque). Vous pouvez bien sûr utiliser ces annotations en même temps.

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