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 -autoNameResolution wsdl地址 
會對類進行重新命名,在執行命令的目錄下會生成客戶端代碼,如下:


這是自動命名的結果。


2.如果我們是開發服務端的,現在僅僅是爲了測試,那我們最好通過溝通來修改接口定義,修改方法返回值的名字,爲了節省工作量,可以直接修改返回值對應的bean上的註解,如將前面代碼修改爲:

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


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

這次可以總結到的最重要的結論是:接口的返回值不要以response結尾,即使想這樣做,也不要造成 "方法名+Response =返回值名” 的情況出現。

 最後要說的就是:“接口規範是誰定義的,出來,讓我踹你兩腳發火

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章