【问题标题】:@XMLRootElement versus @XmlType@XMLRootElement 与 @XmlType
【发布时间】:2012-07-16 06:28:20
【问题描述】:

@XMLRootElement@XMLType 注释类有什么区别。我一直在用 @XMLType 注释类,当结构将在 XML 模式中不止一次使用时,当它只使用一次时,我用 @XMLRootElement 注释 - 这是最好的方法吗?

我将在此处提出一个不同但相关的问题。 @XMLType 注释有一个 propOrder 属性来指定其元素出现的顺序 - @XMLRootElement 是否有等价物?

我将这些注释与 JAX-WS 注释结合使用来创建 Web 服务,如果这有什么不同的话。

【问题讨论】:

    标签: xml jaxb jax-ws


    【解决方案1】:

    XmlRootElementXmlType 之间的区别是范围问题。请记住,此注释只是指示创建用于生成 XML 的模式。 XmlRootElement 表示全局元素(具有匿名或模式类型):

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

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

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

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

    XmlRootElement

    XmlType

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

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

    这将产生类似:

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

    【讨论】:

      【解决方案2】:

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

      要知道的是,@XmlRootElement@XmlType 注释都不是必需的。它们不等同于来自 JPA 的 @Entity。您可以使用 JAXB (JSR-222) 实现而无需任何注释:

      下面我将解释@XmlRootElement@XmlType的作用。


      @XmlRootElement

      有时您的 JAXB 实现需要仅基于正在处理的 XML 元素来实例化对象。 @XmlRootElement 注释是指定此关联的主要方式。请注意,如果一个类对应多个 XML 元素,则应立即使用 @XmlElementDecl 注释,

      ROLE #1 - 指定根对象

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

      Foo

      @XmlRootElement(name="root")
      public class Foo {
      
          private String name;
      
      }
      

      条形

      public class Bar {
      
          private String name;
      
      }
      

      XML

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

      演示

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

      角色 #2 - 替代组

      @XmlElementRef 注释将实例化对象的类型委托给元素的名称/uri。这可以映射到用于表示继承的替换组的概念。

      角色 #3 - 任何内容

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


      @XmlType

      角色 #1 - 架构生成

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

      角色 #2 - 继承和 xsi:type

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

      角色 #3 - 道具顺序

      正如您提到的,您可以使用@XmlType 指定属性顺序。

      角色 #4 - 工厂方法

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


      我将在此处提出一个不同但相关的问题。 @XMLType 注释有一个 propOrder 属性来指定它的顺序 元素出现 - @XMLRootElement 是否有等价物?

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

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

      【讨论】:

        猜你喜欢
        • 2016-08-10
        • 1970-01-01
        • 2010-10-12
        • 2018-01-25
        • 2018-01-26
        • 2014-05-20
        • 1970-01-01
        • 2011-05-18
        • 1970-01-01
        相关资源
        最近更新 更多