兩個類具有相同的 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 =返回值名” 的情況出現。
最後要說的就是:“接口規範是誰定義的,出來,讓我踹你兩腳”