[英]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.