使用JDK wsimport生成Java存根遇ObjectFactory冲突错误求助
我之前也碰到过一模一样的问题——JDK自带的wsimport卡在这里,.NET的svcutil却能顺利生成代码,根源就在于JAXB(wsimport基于它)对Schema里的命名冲突处理比.NET工具严格得多。
从你贴的Schema片段来看,冲突的核心是:你同时有一个名为FilteredQueryArguments的元素,和一个同名的类型(虽然它们来自不同的命名空间q2和q5)。wsimport在生成ObjectFactory类时,会为每个可实例化的元素和类型生成createXxx()方法,这两个同名的元素/类型会导致生成的方法名完全重复,直接触发冲突错误。
下面是几个亲测有效的解决思路:
1. 用JAXB绑定文件自定义命名(无需修改WebService)
这是最常用的解决方案,通过编写一个绑定文件告诉wsimport如何重命名冲突的元素或类型,避免方法名重复。
创建一个名为binding.xml的文件,内容如下(根据你的场景调整):
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" version="2.1"> <!-- 指向你的WSDL文件或Schema地址 --> <jaxb:bindings schemaLocation="http://your-webservice-url?wsdl"> <!-- 重命名冲突的元素,让生成的create方法名带上Element后缀 --> <jaxb:bindings node="//xs:element[@name='FilteredQueryArguments']"> <jaxb:factoryMethod name="createFilteredQueryArgumentsElement"/> </jaxb:bindings> <!-- 或者选择重命名类型,让类型名带上Type后缀 --> <jaxb:bindings node="//xs:complexType[@name='FilteredQueryArguments']"> <jaxb:name>FilteredQueryArgumentsType</jaxb:name> </jaxb:bindings> </jaxb:bindings> </jaxb:bindings>
然后运行wsimport时指定这个绑定文件:
wsimport -b binding.xml http://your-webservice-url?wsdl
这样生成的ObjectFactory里会有createFilteredQueryArgumentsElement()和原来的createFilteredQueryArguments()(对应类型),就不会冲突了。
2. 修改WebService的Schema(如果有权限)
如果能控制WebService的Schema定义,直接从根源上解决问题:给冲突的元素或类型改个名字。比如把那个独立的FilteredQueryArguments元素改成FilteredQueryArgumentsElement,或者把对应的类型改成FilteredQueryArgumentsType。这种方法一劳永逸,后续其他客户端生成代码也不会碰到类似问题。
3. 换用Apache CXF的wsdl2java工具
Apache CXF的wsdl2java工具对命名冲突的处理比JDK的wsimport更智能,默认情况下可能会自动给冲突的方法或类加上后缀,避免冲突。你可以直接用它生成存根:
wsdl2java http://your-webservice-url?wsdl
如果还是有冲突,也可以用CXF的绑定文件做类似的自定义配置,灵活性比wsimport更高。
至于为什么svcutil没问题?因为.NET的工具在处理这种元素和类型同名的场景时,会自动做区分(比如给元素对应的类加上Element后缀,或者生成不同的方法名),不需要手动配置。而JAXB的默认策略比较保守,必须明确告诉它如何处理冲突。
内容的提问来源于stack exchange,提问作者Alex

