在我想要预定义 java 对象列表的位置获取 JAXBElement 列表

Getting a list of JAXBElement where I want a list of predefined java objects

我使用 Apache Camel + JAXB 进行 Soap 处理。 java 眼镜由名为 cxf-codegen-plugin 的 maven 插件生成。

我面临的问题是,当我想使用 属性 这是一个列表时。在那种情况下,我将始终获得 JAXBElement 列表而不是正确 class.

的对象

假设给定 xml 剪断:

<domainObjects avqxsi:type="avqsq:AssetAllocation" id="100" name="Some Name">
    <nodes>101</nodes>
    <nodes>102</nodes>
  </domainObjects>

现在所有 "nodes" 都是 AANode 类型的不同域对象的 ID。所以在 xsd 中它是这样定义的:

<xsd:complexType name="AssetAllocation">
    <xsd:complexContent>
      <xsd:extension base="avqsq:DomainObject">
        <xsd:sequence>
          <xsd:element ecore:reference="avqsq:AANode" maxOccurs="unbounded" name="nodes" type="xsd:IDREF"/>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

我定义了一些bindings.xml:

<jaxb:bindings node="xsd:complexType[@name='AssetAllocation']//xsd:element[@name='nodes']">
            <jaxb:property>
                <jaxb:baseType name="my.api.xsd.AANode"/>
            </jaxb:property>
        </jaxb:bindings>

我要的是这样的POJO属性:

@XmlElementRef(name = "nodes")
protected List<AANode> nodes;

但我在 运行时 实际得到的是 List<JAXBElement<AANode>> 导致 ClassCastException。

编辑 1: 我错过了 cxf-codegen 框架正在生成 class 的事实,您可以清楚地看到 属性 带有 JAXBElement.class 注释,我认为这是错误的。有趣的是,手动将注释更改为 AANode.class 将失败并出现 IllegalAnnotationException: AANode" 或其任何子 class 在此上下文中未知。

public class AssetAllocation
    extends DomainObject
    implements Serializable, Equals, HashCode, ToString
{

    @XmlElementRef(name = "nodes", type = JAXBElement.class)
    protected List<AANode> nodes;

apache CXF 代码生成插件将始终使用 JAXBElement 生成代码,直到您设置生成元素 属性 标志。

请创建 Jaxb binding.xml 并在 pom 文件的代码生成插件部分引用该绑定 xml,如下所示

binding.xml

<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings version="2.0"
               xmlns:jaxb="http://java.sun.com/xml/ns/jaxb">
    <jaxb:bindings>
        <jaxb:globalBindings generateElementProperty="false"/>
    </jaxb:bindings>
</jaxb:bindings>

代码生成插件

<plugin>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-codegen-plugin</artifactId>
                <version>3.1.1</version>
                <executions>
                    <execution>
                        <id>generate-sources</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>wsdl2java</goal>
                        </goals>
                        <configuration>
                            <wsdlOptions>
                                <wsdlOption>
                                    <wsdl>${basedir}/src/main/resources/META-INF/wsdl/CxfExampleService.wsdl</wsdl>
                                    <bindingFiles>
                                        <bindingFile>${basedir}/src/main/resources/META-INF/wsdl/binding/bindings.xml</bindingFile>
                                    </bindingFiles>                                 
                                </wsdlOption>
                            </wsdlOptions>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

这将解决问题

事实上,wsdl2java 生成的 类 带有错误的注释。而不是

@XmlElementRef(name = "nodes", type = JAXBElement.class)
protected List<AANode> nodes;

人们期望拥有:

@XmlIDREF
protected List<AANode> nodes;

我无法通过 bindings.xml 来管理它。所以我的最终解决方案是使用字节码操作来修复注释。这样我就不必弄乱生成的 类 或生成器本身。