我使用Apache Camel + JAXB进行肥皂处理。 Java眼镜由名为cxf-codegen-plugin的Maven插件生成。

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

假定此给定的xml被截断:

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


现在,所有“节点”都是类型为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框架正在生成一个类的事实,您可以清楚地看到该属性用JAXBElement.class注释,我认为这是错误的。有趣的是,将注释手动更改为ANode.class会失败,并出现IllegalAnnotationException:AANode“或此上下文不知道其任何子类。

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

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

最佳答案

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

请创建Jaxb binding.xml,并从pom文件中的代码生成插件部分中引用该绑定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>


这样可以解决问题

09-30 23:12