Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JAXB覆盖@XmlElement列表类型_Java_Jaxb_Unmarshalling_Xmladapter - Fatal编程技术网

Java JAXB覆盖@XmlElement列表类型

Java JAXB覆盖@XmlElement列表类型,java,jaxb,unmarshalling,xmladapter,Java,Jaxb,Unmarshalling,Xmladapter,有一个简单的类Bean1,其子列表类型为BeanChild1 @XmlRootElement(name="bean") @XmlAccessorType(XmlAccessType.PROPERTY) public static class Bean1 { public Bean1() { super(); } private List<BeanChild1> childList = new ArrayList<>(); @XmlEleme

有一个简单的类
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 { ... }
下面是我如何测试它的:

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
}
publicstaticvoidmain(字符串[]args)
{
字符串xml=“”+
"  " +
"  " +
"  " +
"";
Reader=新的StringReader(xml);
bean2b2=JAXB.unmarshal(reader,Bean2.class);
断言b2.getChildList().get(0)BeanChild2的实例;//失败
}
测试显示此列表仍然包含
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
实例填充
childList
字段呢?

如果没有简单的解决方案,请随意发布更具创造性的解决方案(例如,使用
XmlAdapter
s、
Unmarshaller.Listener
,可能是父类或子类上的附加注释…)

无法更改(例如重写)超类的
@xmlement
注释。至少不使用注释

  • 您使用的
    @xmlacessortype
    并不重要(例如
    字段
    属性
    公共
  • 如果将注释放在字段或getter上,则没有任何区别
然而,有一个合理的选择。JAXB的MOXy实现提供了以下功能:。事实上,每个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);
//使用映射引用xml文件
Map propertyMap=新HashMap();
propertyMap.put(JAXBContextProperties.OXM_METADATA_源代码,“bindings.xml”);
//在创建JAXB上下文期间传递此PropertyMap。
JAXBContext context=JAXBContext.newInstance(…,propertyMap);
MOXy将合并java注释和XML绑定,如果发生冲突,将应用XML定义的设置。在本例中,前面的
@xmlement(name=child)
注释被一个xml定义替换,该定义相当于
@xmlement(name=child,type=BeanChild2.class)

您可以阅读有关XML绑定的更多信息