java 继承和 JAXB 如何协同工作?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13928222/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do Inheritance and JAXB work together?
提问by Narendra Pathai
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";
}
As I have shown in the example when I removethe @XmlTransient
from the Parent
class getList()
method, following xml is marshalled:
正如我在例如已经显示,当我删除的@XmlTransient
从Parent
类getList()
方法,下面的XML被编组:
<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>
But when I addthe @XmlTransient
annotation, as in the example the xml is serialized with only ONElist as required.
但是,当我加了@XmlTransient
注释,如本例中的XML仅与序列化ONE的要求清单。
<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>
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?
所以请有人解释我为什么需要@XmlTransient
在父类 getter 方法中给出?在这些情况下,继承和 JAXB 如何相互关联?
采纳答案by bdoughan
WHY ITS HAPPENING
为什么会发生
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
).
甲JAXB(JSR-222)实施将映射的每个域对象,它意识到的复杂类型。这意味着它认为该类存在以下 XML 类型Parent
(当list
不存在时@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>
Now Child2
also has a complex type. There are two things JAXB could have done:
现在Child2
也有复杂类型。JAXB 可以做两件事:
- 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 extendsparent
. This means it gets all the elements from theparent
type plus its own.
- 不允许覆盖属性,这将是非常有限的。
- 为覆盖的属性生成附加映射。在下面的架构中,
child2
类型 extendsparent
。这意味着它从parent
类型中获取所有元素加上它自己的元素。
<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>
HOW TO FIX IT
如何修复
You could put @XmlTransient
on the list
property in the Parent
class, but instead I would recommend annotating the Parent
class with @XmlTransient
.
你可以把@XmlTransient
关于list
在房地产Parent
类,而是我会建议注释的Parent
带班@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);
}
This will remove it as a mapped class and the complex type that corresponds to Child2
will become:
这会将其作为映射类删除,对应的复杂类型Child2
将变为:
<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>