有一个简单的类Bean1
,其子列表类型为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
)。
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 { }
所以,这是我测试它的方式:
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
}
测试显示此列表仍包含BeanChild1
的孩子。
那么,如何强制它使用childList
个实例填充BeanChild2
字段?
如果没有简单的解决方案,请随时发布更具创意的解决方案(例如,使用XmlAdapter
s,Unmarshaller.Listener
,或许在父类或子类上添加其他注释...)
答案 0 :(得分:0)
无法更改(例如覆盖)超类的@XmlElement
注释。至少不使用注释。
@XmlAccessorType
的内容并不重要(例如FIELD
,PROPERTY
,PUBLIC
,NONE
)。然而,有一个合理的选择。 JAXB的MOXy实现提供define the metadata/bindings in an xml file的能力。事实上,每个java注释都有一个XML替代方案。但它会变得更好:你可以将java注释和这些xml元数据结合起来。很酷的是,MOXy会合并两个声明,如果发生冲突, XML定义的元数据会得到一个更高的优先级。
假设Bean1
类注释如上。然后可以在xml文件中重新定义绑定。 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>
在创建上下文对象时需要这个新的绑定文件。
// 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)
。
您可以阅读有关XML绑定here的更多信息。