【问题标题】:Getting a list of JAXBElement where I want a list of predefined java objects获取 JAXBElement 列表,其中我想要预定义的 java 对象列表
【发布时间】:2015-08-25 14:16:42
【问题描述】:

我使用 Apache Camel + JAXB 进行 Soap 处理。 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;

但我在 runtime 实际得到的是 List&lt;JAXBElement&lt;AANode&gt;&gt;,它会导致 ClassCastException。

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

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

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

【问题讨论】:

    标签: java soap jaxb apache-camel cxf-codegen-plugin


    【解决方案1】:

    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>
    

    这将解决问题

    【讨论】:

    • 嗯,我已经尝试过了,它也以这种方式记录,但我无法获得预期的行为。
    【解决方案2】:

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

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

    人们期望拥有:

    @XmlIDREF
    protected List<AANode> nodes;
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-07
      • 1970-01-01
      • 2012-01-30
      • 1970-01-01
      • 2014-09-28
      • 1970-01-01
      • 2021-09-16
      • 2023-02-07
      相关资源
      最近更新 更多