JAXB覆盖@XmlElement类型的列表 [英] JAXB override @XmlElement type of list
问题描述
有一个简单的类 Bean1
,其子列表类型为 BeanChild1
。
There's a simple class Bean1
with a sublist of type BeanChild1
.
@XmlRootElement(name="bean")
@XmlAccessorType(XmlAccessType.PROPERTY)
public static class Bean1
{
public Bean1()
{
super();
}
private List<BeanChild1> childList = new ArrayList<>();
@XmlElement(name="child")
public List<BeanChild1> getChildList()
{
return childList;
}
public void setChildList(List<BeanChild1> pChildList)
{
childList = pChildList;
}
}
public static class BeanChild1 { ... }
我试图覆盖该类,以更改列表的类型。
新的子类(即 BeanChild2
)扩展了前一个(即 BeanChild1
)。
I am trying to override the class, to change the type of the list.
The new child-class (i.e. BeanChild2
) extends the previous one (i.e. BeanChild1
) .
public static class Bean2 extends Bean1
{
public Bean2()
{
super();
}
@Override
@XmlElement(name="child", type=BeanChild2.class)
public List<BeanChild1> getChildList()
{
return super.getChildList();
}
}
public static class BeanChild2 extends BeanChild1 { }
所以,这是我测试它的方式:
So, here is how I tested it:
public static void main(String[] args)
{
String xml = "<bean>" +
" <child></child>" +
" <child></child>" +
" <child></child>" +
"</bean>";
Reader reader = new StringReader(xml);
Bean2 b2 = JAXB.unmarshal(reader, Bean2.class);
assert b2.getChildList().get(0) instanceof BeanChild2; // fails
}
测试显示此列表仍包含<$的子项c $ c> BeanChild1 。
The test reveals that that this list still contains childs of BeanChild1
.
那么,如何强制它填充 childList
字段 BeanChild2
实例?
So, how can I force it to populate the childList
field with BeanChild2
instances ?
如果没有简单的解决方案,那么随意发布更具创意的解决方案(例如使用 XmlAdapter
s, Unmarshaller.Listener
,也许是父母的额外注释或儿童班......)
If there are no easy solutions, then feel free to post more creative solutions (e.g. using XmlAdapter
s, Unmarshaller.Listener
, perhaps an additional annotation on the parent or child class ...)
推荐答案
无法改变(例如覆盖) @ XmlElement
超类的注释。至少不使用注释。
There is no way to change (e.g. override) the @XmlElement
annotation of a super class. At least not using annotations.
- 你使用的
@XmlAccessorType
并不重要(例如FIELD
,PROPERTY
,PUBLIC
,NONE
)。 - 如果将注释放在字段或getter上,则没有任何区别。
- It doesn't matter what
@XmlAccessorType
you use (e.g.FIELD
,PROPERTY
,PUBLIC
,NONE
). - It doesn't make any difference if you put the annotations on the fields or on the getters.
然而,有一个合理的选择。 JAXB的MOXy实现提供了在xml文件中定义元数据/绑定的能力。事实上,每个java注释都有一个XML替代方案。但它会变得更好:你可以将java注释和这些xml元数据结合起来。很酷的是,MOXy会合并两个声明,如果发生冲突, XML定义的元数据会得到一个优先级较高。
However, there is a reasonable alternative. The MOXy implementation of JAXB offers the ability to define the metadata/bindings in an xml file. In fact every java annotation has an XML alternative. But it gets better: You can combine both java annotations AND these xml metadata. The cool thing, is that MOXy will merge both declarations, and in case of conflict, the XML defined metadata gets a higher priority.
假设 Bean1
类如上所示进行注释。然后可以在xml文件中重新定义绑定。例如:
Assuming that the Bean1
class is annotated as above. Then it's possible to redefine the binding, in an xml file. e.g.:
<xml-bindings xml-accessor-type="PROPERTY">
<java-types>
<java-type name="Bean1">
<xml-element java-attribute="childList" name="child"
type="BeanChild2" container-type="java.util.ArrayList" />
</java-type>
</java-types>
</xml-bindings>
在创建上下文对象时需要这个新的绑定文件。
This new bindings file is needed during the creation of the context object.
// use a map to reference the xml file
Map<String, Object> propertyMap = new HashMap<>();
propertyMap.put(JAXBContextProperties.OXM_METADATA_SOURCE, "bindings.xml");
// pass this properyMap during the creation of the JAXB context.
JAXBContext context = JAXBContext.newInstance(..., propertyMap);
MOXy将合并java注释和XML绑定,如果发生冲突,则会定义XML定义的设置适用。在这种情况下,早期的 @XmlElement(name = child)
注释被xml定义替换,该定义等同于 @XmlElement(name = child, type = BeanChild2.class)
。
MOXy will merge the java annotations and the XML bindings, and in case of a conflict the XML defined settings are applied. In this case, the earlier @XmlElement(name=child)
annotation is replaced by an xml definition which is equivalent to @XmlElement(name=child, type=BeanChild2.class)
.
您可以阅读有关XML绑定的更多信息这里。
You can read more about the XML bindings here.
这篇关于JAXB覆盖@XmlElement类型的列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!