繁体   English   中英

使用CXF和wsdl2java生成代码时解决冲突

[英]Resolving conflicts when generating code with CXF and wsdl2java

在使用wsdl2java通过cxf-codegen-plugin和Maven从一堆WSDL文件生成代码的过程中,我遇到了一些冲突。 WSDL声明同一系统的不同API,并且生成的代码具有一定程度的重叠(尤其是与模型类重叠)。 外部系统和WSDL来自第三方,因此不受我们的控制。

我遇到的第一个问题是由其中一个WSDL导致的结果ObjectFactory类之一的命名冲突。 它定义了一个名为Foo的complexType,其中包含一个名为Status的元素,并且还定义了一个名为FooStatus的元素。 生成代码时,JAXB会抛出错误,因为ObjectFactory将有两个名称为createFooStatus(...)工厂方法,并且在运行时出现异常。 我尝试向-autoNameResolution提供选项-autoNameResolution,但无济于事。 我研究了“两个声明在ObjectFactory类中引起冲突”“将外部JAXB绑定文件应用于从WSDL导入的架构元素” ,并基于这些内容编写了一个重命名工厂方法之一的外部绑定文件。 。 我在绑定文件中使用SCD代替XPath,如后面的链接所示,因为XPath与作者存在相同的问题。 这是可行的,但是仅当我分别处理WSDL文件并将绑定文件仅应用于导致冲突的WSDL时才有效。 Maven配置如下所示:

<plugin>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-codegen-plugin</artifactId>
  <version>3.0.0-milestone1</version>
  <executions>
    <execution>
      <id>generate-proxies</id>
      <phase>generate-sources</phase>
      <configuration>
        <wsdlOptions>
          <wsdlOption>
            <wsdl>${basedir}/First.wsdl</wsdl>
            <bindingFiles>
              <bindingFile>${basedir}/bindings.xml</bindingFile>
            </bindingFiles>
          </wsdlOption>
          <wsdlOption>
            <wsdl>${basedir}/Second.wsdl</wsdl>
          </wsdlOption>
          <wsdlOption>
            <wsdl>${basedir}/Third.wsdl</wsdl>
          </wsdlOption>
          ... More wsdlOption declarations ...
        </wsdlOptions>
      </configuration>
      <goals>
        <goal>wsdl2java</goal>
      </goals>
    </execution>
  </executions>
</plugin>

现在,如果这样做,我将面临另一个问题,因为从不同的WSDL文件生成的代码使用相同的包结构。 实际上,这意味着在处理后续的WSDL文件时, ObjectFactory类将被覆盖,这意味着在插件执行之后,将仅存在从最后一个WSDL生成的文件。 我知道我可以更改目标程序包的结构,但是从不同的WSDL生成的代码有很多重叠,并且复制它会感到很愚蠢。 我使用还试图-keep WSDL2Java的选项,但似乎并没有做任何事情(或者至少是ObjectFactory类仍然得到覆盖)。 我的理解是,解决方案是使用这样的Maven配置一次性处理所有WSDL(仅显示配置部分,所有其他保持不变):

<configuration>
  <defaultOptions>
    <bindingFiles>
      <bindingFile>${basedir}/bindings.xml</bindingFile>
    </bindingFiles>
  </defaultOptions>
  <wsdlRoot>${basedir}</wsdlRoot>
  <includes>
    <include>*.wsdl</include>
  </includes>
</configuration>

但是,这导致com.sun.istack.SAXParseException2 ,说我的SCD表达式与任何模式组件都不匹配(因为模式组件仅存在于WSDL之一中)。

如果修改WSDL文件本身并使用不带绑定文件的后者Maven配置,则可以获得所需的结果。 这样,生成的ObjectFactory是合并后的合并对象,该合并将在使用第一个Maven配置分别处理WSDL时创建。 但是,我不想这样做,而是想使用一个外部绑定文件来管理它。 我应该如何解决这个问题? 我是否可以编写/应用绑定文件,以便在找不到匹配的架构组件时不引发异常? 还是可以单独处理WSDL而不覆盖ObjectFactory类? 还是只需要吸收它,或者将代码从不同的WSDL生成到不同的程序包,或者自己编辑WSDL文件? 以防万一,我当前的绑定文件如下所示(WSDL与绑定文件位于同一目录下的项目中):

<bindings scd="x-schema::tns" xmlns:tns="NamespaceOfFoo" xmlns="http://java.sun.com/xml/ns/jaxb" version="2.1">
  <bindings scd="tns:FooStatus">
    <factoryMethod name="FooStatusType"/>
  </bindings>
</bindings>

经过更多的谷歌搜索和阅读论坛帖子后,我最终解决了这个问题。 我设法使用XPath(而不是SCD)编写了外部绑定文件,这种方式仅针对我感兴趣的节点,而在处理其他WSDL文件时不会出错。 最初使我无法使用XPath定位WSDL中的节点的主要混乱原因是JAXB和JAXWS命名空间的相似XML模式(都定义了元素“绑定”,而我在这里看到的大多数教程都使用JAXB版本)我必须使用JAXWS版本)。 生成的绑定文件如下所示:

<jaxws:bindings xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
                xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
                wsdlLocation="First.wsdl"
                version="2.1">
  <jaxws:bindings node="wsdl:definitions/wsdl:types/xsd:schema/xsd:element[@name='FooStatus']">
    <jaxb:factoryMethod name="FooStatusType"/>
  </jaxws:bindings>
</jaxws:bindings>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM