@XMLRootElement与@XmlType

Cod*_*ber 37 xml jax-ws jaxb

@XMLRootElement和注释一个类有什么区别@XMLType.我一直在注释类@XMLType的结构将在XML模式中多次使用,@XMLRootElement何时只使用一次 - 这是最好的方法吗?

一个不同但相关的问题,我将在这里包括.该@XMLType标注有一个propOrder属性来指定其中责令其元素出现-是有一个相当于为@XMLRootElement

我正在使用这些注释与JAX-WS注释一起创建Web服务,如果这有任何区别的话.

Doc*_*son 21

XmlRootElement和之间的区别XmlType是范围问题.请记住,此注释仅指示用于生成XML的模式的创建.的XmlRootElement表示一个全局元素(与匿名或模式类型):

<xs:element name=foo type="bar"> </xs:element> <-- schema type
Run Code Online (Sandbox Code Playgroud)

XmlType用于表示本地元素(具有匿名或复杂类型):

<xs:complexType name=bar> </xs:complexType> <-- complex type
Run Code Online (Sandbox Code Playgroud)

本地/全局的主要区别在于您的对象将出现在的架构的层次结构中,以及您是否声明架构类型或复杂类型.这两个注释的文档都写得很好,包括以下示例:

XmlRootElement

XmlType

编辑:解决propOrder问题:如果您还声明了本地类型,则可以在全局元素上使用它:

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

这将产生类似于:

<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>
Run Code Online (Sandbox Code Playgroud)


bdo*_*han 17

当结构将在XML模式中多次使用时,我一直用@XMLType注释类,而当它只使用一次时使用@XMLRootElement - 这是最好的方法吗?

有一点需要知道的是,无论是@XmlRootElement@XmlType注释是必需的.它们不等同@Entity于JPA.你可以使用JAXB(JSR-222)实现而不需要任何注释:

下面我将解释什么@XmlRootElement@XmlType做.


@XmlRootElement

有时,您的JAXB实现需要仅基于正在处理的XML元素来实例化对象.的@XmlRootElement注释是指定此关联的主要手段.注意,如果一个类对应多个XML元素,那么@XmlElementDecl应该使用insteat注释,

角色#1 - 指定根对象

@XmlRootElement主要用于指定根对象.当您的JAXB实现开始解组XML文档时,它就知道了要实例化的对象.几乎所有后续注释都将基于从父类收集的信息.

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

    private String name;

}
Run Code Online (Sandbox Code Playgroud)

酒吧

public class Bar {

    private String name;

}
Run Code Online (Sandbox Code Playgroud)

XML

<root>
    <name>Jane Doe</name>
</root>
Run Code Online (Sandbox Code Playgroud)

演示

Foo foo = (Foo) unmarshaller.unmarshal(xml);
Bar bar = unmarshaller.unmarshal(xml, Bar.class).getValue();
Run Code Online (Sandbox Code Playgroud)

角色#2 - 替代组

@XmlElementRef注释的代表对象的实例化的元素的名称/ URI的类型.这使得映射到替换组的概念以表示继承.

角色#3 - 任何内容

@XmlAnyElement允许您映射XML文档的通配符部分.如果指定@XmlAnyElement(lax=true)那么与域对象关联的元素将转换为相应的域对象.


@XmlType

角色#1 - Schema Gen

默认情况下,为JAXB上下文已知的每个Java类生成命名复杂类型.您可以使用@XmlType注释控制此类型的名称,或指定应通过将名称指定为生成匿名复杂类型"".

角色#2 - 继承和xsi:类型

默认情况下,JAXB利用该xsi:type属性作为继承指示符.此属性上的值对应于您在@XmlType注释上指定的名称和名称空间,或者基于类进行默认.

角色#3 - 道具顺序

如您所述@XmlType,您可以使用它来指定属性顺序.

角色#4 - 工厂方法

@XmlType 允许您指定可用于实例化域对象而不是默认构造函数的工厂类和/或方法.


一个不同但相关的问题,我将在这里包括.@XMLType注释有一个propOrder属性来指定它的元素出现的顺序 - 是否有@XMLRootElement的等价物?

不,该propOrder方面属于@XmlType注释.这是有道理的,因为复杂类型负责指定(或缺少)顺序.您当然可以同时使用这些注释.

@XmlRootElement
@XmlType(propOrder={"foo", "bar"}
public class Root {
    ...
}
Run Code Online (Sandbox Code Playgroud)