继承和JAXB如何协同工作? [英] How do Inheritance and JAXB work together?

查看:59
本文介绍了继承和JAXB如何协同工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

public abstract class Parent<T> {
    protected List<T> list;

    @XmlTransient   //Question why do we have to give this here?
    public abstract List<T> getList();
    public abstract void setList(List<T> list);
}

@XmlRootElement(name = "child1")
class Child1 extends Parent<ExtendedElement1>{
    @Override
    public void setList(List<ExtendedElement1> list){
        this.list = list;
    }

    @Override
    @XmlElementWrapper(name = "child1-list")
    @XmlElement(name = "child-list-element")
    public List<ExtendedElement1> getList(){
        return this.list;
    }
}

@XmlRootElement(name = "child2")
class Child2 extends Parent<ExtendedElement2>{
    @Override
    public void setList(List<ExtendedElement2> list){
        this.list = list;
    }

    @Override
    @XmlElementWrapper(name = "child1-list")
    @XmlElement(name = "child-list-element")
    public List<ExtendedElement2> getList(){
        return this.list;
    }
}


class Element{
    @XmlElement(name = "integer", type = int.class)
    private int i = 2;
}

class ExtendedElement1 extends Element{
    @XmlElement(name = "extended-element1-str", type = String.class)
    private String str = "hello";
}

class ExtendedElement2 extends Element{
    @XmlElement(name = "extended-element2-str", type = String.class)
    private String str1 = "hello_there";
}

正如我在示例中所示删除 @XmlTransient 来自 getList()方法,以下xml被编组:

As I have shown in the example when I remove the @XmlTransient from the Parent class getList() method, following xml is marshalled:

<child1>
<!-- List is serialized 2 times -->
    <list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="extendedElement1">
        <integer>2</integer>
        <extended-element1-str>hello</extended-element1-str>
    </list>
    <list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="extendedElement1">
        <integer>2</integer>
        <extended-element1-str>hello</extended-element1-str>
    </list>
    <list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="extendedElement1">
        <integer>2</integer>
        <extended-element1-str>hello</extended-element1-str>
    </list>
    <child1-list>
        <child-list-element>
            <integer>2</integer>
            <extended-element1-str>hello</extended-element1-str>
        </child-list-element>
        <child-list-element>
            <integer>2</integer>
            <extended-element1-str>hello</extended-element1-str>
        </child-list-element>
        <child-list-element>
            <integer>2</integer>
            <extended-element1-str>hello</extended-element1-str>
        </child-list-element>
    </child1-list>
</child1>

但当我添加 @XmlTransient 注释,在示例中,xml根据需要仅按 ONE 列表进行序列化。

But when I add the @XmlTransient annotation, as in the example the xml is serialized with only ONE list as required.

<child1>
    <child1-list>
        <child-list-element>
            <integer>2</integer>
            <extended-element1-str>hello</extended-element1-str>
        </child-list-element>
        <child-list-element>
            <integer>2</integer>
            <extended-element1-str>hello</extended-element1-str>
        </child-list-element>
        <child-list-element>
            <integer>2</integer>
            <extended-element1-str>hello</extended-element1-str>
        </child-list-element>
    </child1-list>
</child1>

所以请有人解释我为什么需要提供 @XmlTransient <父类getter方法中的/ code>?对于这些情况,继承和JAXB如何相互关联?

So please can someone explain me why is it required to give @XmlTransient in Parent Class getter method? How does inheritance and JAXB inter-relate for these cases?

推荐答案

为什么会发生

JAXB(JSR-222) 实现会将其知道的每个域对象映射到复杂类型。这意味着它认为 Parent 类存在以下XML类型(当 list 不是 @XmlTransient )。

A JAXB (JSR-222) implementation will map every domain object that it is aware of to a complex type. This means it believes that the following XML type exists for the Parent class (when list is not @XmlTransient).

  <xs:complexType name="parent" abstract="true">
    <xs:sequence>
      <xs:element name="list" type="xs:anyType" nillable="true" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

现在 Child2 也有复杂类型。 JAXB可以做两件事:

Now Child2 also has a complex type. There are two things JAXB could have done:


  • 不允许覆盖属性,这将是非常有限的。

  • 为重写的属性生成其他映射。在下面的模式中, child2 类型扩展 parent 。这意味着它从类型加上它自己的所有元素。

  • Not allow properties to be overridden, which would be pretty limiting.
  • Generate an additional mapping for the overridden property. In the schema below the child2 type extends parent. This means it gets all the elements from the parent type plus its own.
  <xs:complexType name="child2">
    <xs:complexContent>
      <xs:extension base="parent">
        <xs:sequence>
          <xs:element name="child1-list" minOccurs="0">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="child-list-element" type="extendedElement2" minOccurs="0" maxOccurs="unbounded"/>
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>

如何修复

您可以在 Parent <中的列表属性中放置 @XmlTransient / code> class,但我建议使用 @XmlTransient 注释 Parent 类。

You could put @XmlTransient on the list property in the Parent class, but instead I would recommend annotating the Parent class with @XmlTransient.

import java.util.List;
import javax.xml.bind.annotation.XmlTransient;

@XmlTransient
public abstract class Parent<T> {
    protected List<T> list;

    public abstract List<T> getList();
    public abstract void setList(List<T> list);

}

这将把它作为映射类和复杂类型删除对应 Child2 将变为:

This will remove it as a mapped class and the complex type that corresponds to Child2 will become:

  <xs:complexType name="child2">
    <xs:sequence>
      <xs:element name="child1-list" minOccurs="0">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="child-list-element" type="extendedElement2" minOccurs="0" maxOccurs="unbounded"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>

这篇关于继承和JAXB如何协同工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆