两个类具有相同的 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.SearchAccountBatchResponsethis 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>
综合结论一和结论二,我们就可以发现报错的原因:因为程序试图在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的如下命令:
这是自动命名的结果。
2.如果我们是开发服务端的,现在仅仅是为了测试,那我们最好通过沟通来修改接口定义,修改方法返回值的名字,为了节省工作量,可以直接修改返回值对应的bean上的注解,如将前面代码修改为:
@XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "SearchAccountBatchResult") public class SearchAccountBatchResponse {*******}
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
这次可以总结到的最重要的结论是:接口的返回值不要以response结尾,即使想这样做,也不要造成 "方法名+Response =返回值名” 的情况出现。
最后要说的就是:“接口规范是谁定义的,出来,让我踹你两脚”