Exception:两个类具有相同的 XML 类型名称,请使用 @XmlType.name 和 @XmlType.namespace 为类分配不同的名称

前端之家收集整理的这篇文章主要介绍了Exception:两个类具有相同的 XML 类型名称,请使用 @XmlType.name 和 @XmlType.namespace 为类分配不同的名称前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

两个类具有相同的 XML 类型名称

"{http://service.webservice.base.xm/}searchAccountBatchResponse"。

请使用 @XmlType.name 和 @XmlType.namespace 为类分配不同的名称

this problem is related to the following location:
at xm.base.webservice.model.SearchAccountBatchResponse

at private xm.base.webservice.model.SearchAccountBatchResponse xm.base.webservice.service.jaxws_asm.SearchAccountBatchResponse._return

at xm.base.webservice.service.jaxws_asm.SearchAccountBatchResponse
this problem is related to the following location:

at xm.base.webservice.service.jaxws_asm.SearchAccountBatchResponse


在进行webservice开发的时候,启动tomcat后报了如上异常。

@WebMethod
	public SearchAccountBatchResponse searchAccountBatch(@WebParam(name = "searchAccountBatchRequest") SearchAccountBatchRequest searchAccountBatchRequest){}
先观察这个方法,这个方法生成wsdl文件时会生成如下两行:
<xs:element name="searchAccountBatch" type="tns:searchAccountBatch"/>
<xs:element name="searchAccountBatchResponse" type="tns:searchAccountBatchResponse"/>

第一行表示这个方法,第二行是jax_ws在解析时会根据每一个方法生成一个对应的元素,名称为:方法名+Response,在这里就是 searchAccountBatchResponse

为了验证这一点,写如下方法

@WebMethod
	public ResultBase oilStationInfoSyn(StationsInfo stationsInfo){****}
这个可以正常运行并生成wsdl文件,对应的那两行的内容为:

<xs:element name="oilStationInfoSyn" type="tns:oilStationInfoSyn"/>
<xs:element name="oilStationInfoSynResponse" type="tns:oilStationInfoSynResponse"/>

也就是说上面的说法成立,我们得出如下结论:

结论1:jax_ws在解析时会根据每一个方法生成一个对应的元素,名称为:方法名+Response

————————————————————————————————————————————————————————

继续,该方法的返回值为SearchAccountBatchResponse,在生成wsdl文件时会生成如下代码

<xs:complexType name="searchAccountBatchResponse">
<xs:sequence>
<xs:element minOccurs="0" name="requestID" type="xs:string"/>
<xs:element minOccurs="0" name="returnCode" type="xs:string"/>
<xs:element minOccurs="0" name="returnMessage" type="xs:string"/>
<xs:element name="returnFlag" type="xs:boolean"/>
<xs:element name="isComplete" type="xs:boolean"/>
<xs:element name="accountInfoSize" type="xs:int"/>
<xs:element maxOccurs="unbounded" minOccurs="0" name="accountInfoList" nillable="true" type="tns:accountInfo"/>
</xs:sequence>
</xs:complexType>

当然,因为程序启动不起来,所以没办法看到生成的wsdl文件,所以仍然用刚才的那个类去验证,结果如下:

<xs:complexType name="resultBase">
<xs:sequence>
<xs:element minOccurs="0" name="ResultCode" type="xs:string"/>
<xs:element minOccurs="0" name="ExceptionMessage" type="xs:string"/>
<xs:element minOccurs="0" name="ResultMsg" type="xs:string"/>
</xs:sequence>
</xs:complexType>

SearchAccountBatchResponse和ResultBase是两个javabean,在生成wsdl文件时会生成对应的xml文件元素,其中类型名为类名的首字母小写,即 searchAccountBatchResponse和resultBase于是我们的出下面的结论:
结论2:在生成wsdl文件时,返回值对应的javaBean会在wsdl文件生成对应的元素,类型名为类名首字母小写后的结果

----------------------------------------------------------------------------------------------------------------------------

综合结论一和结论二,我们就可以发现报错的原因:因为程序试图在wsdl文件中写入两个类型名相同的元素

那我们该怎么解决呢?

-----------------------------------------------------------------------------------------------------------------------------

第一种方法是:修改方法名,理由应该是显而易见的,可以根据结论一得出

第二种方法是:使用JAXB的注解去指定返回值对应的javabean在生成的wsdl中对应的名字

由于接口的定义事先已经约定好了,所以排除第一种方法,先来试试第二种方法

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "SearchAccountBatchResponse")
public class SearchAccountBatchResponse
{*****}
这种方法是指定该bean对应的wsdl的文件中的类型名为SearchAccountResponse,首字母是大写的,所以不会发生之前的异常。

程序可以正确运行,并可以访问到wsdl文件

----------------------------------------------------------------------------------------------------------------------------

难道这样就可以了吗?其实并没有 当我试图去生成客户端代码的时候出现了如下异常:


当然,因为我的这个接口里有多个方法,所以报的不是同一个方法的错,只报了其中的一个,这个是我用Myeclipse生成客户端是出现的,当我用cxf的wsdl2java 命令去生成客户端时,也会报同样的错。

很纠结,是什么原因呢?这是因为wsdl中存在一个SearchAccountResponse和一个searchAccountResponse,在生成对应的java类时自然都是首字母大写,即生成SearchAccountResponse.java,当程序试图生成两个同样的类时,就会报这个错:类或接口已经存在了

--------------------------------------------------------------------------------------------------------------------

上面的问题得分情况解决

1.如果服务端已经写好了,我们是根据现有的wsdl文件生成客户端,那我们只能使用wsdl的如下命令:

wsdl2java-autoNameResolutionwsdl地址
会对类进行重新命名,在执行命令的目录下会生成客户端代码,如下:


这是自动命名的结果。


2.如果我们是开发服务端的,现在仅仅是为了测试,那我们最好通过沟通来修改接口定义,修改方法返回值的名字,为了节省工作量,可以直接修改返回值对应的bean上的注解,如将前面代码修改为:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "SearchAccountBatchResult")
public class SearchAccountBatchResponse
{*******}


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

这次可以总结到的最重要的结论是:接口的返回值不要以response结尾,即使想这样做,也不要造成 "方法名+Response =返回值名” 的情况出现。

最后要说的就是:“接口规范是谁定义的,出来,让我踹你两脚”

猜你在找的XML相关文章