1. 程式人生 > >webservice客戶端名稱空間

webservice客戶端名稱空間

一:開發背景

webservice通訊時經常會遇到名稱空間不符的情況,比如全系統統一使用一套規範,但是某些系統提供的服務命名不是很統一,由其提供的wsdl檔案生成的客戶端的名稱空間也隨之不統一,因此就需要呼叫方開發客戶端時修改名稱空間。

1:全系統統一使用的名稱空間

<soapenv:envelope
xmlns:soapenv="http://shcemas.xnlsoap.org/soap/envelope/"
xmlns:s="http://127.0.0.1:8888/UPB"
xmlns:tns="http://127.0.0.1:8888/UPB/wsdl">
	<soapenv:Header/>
	<soapenv:Body>
		<tns:ReqS00000000001>
			<s:ReqSysHead>
				<s:SvcId>?</s:SvcId>
				<s:SvcScn>?</s:SvcScn>
			</s:ReqSysHead>
		</tns:ReqS00000000001>
	</soapenv:Body>
</soapenv:envelope>

2:其他系統提供的webservice服務

<soapenv:envelope
xmlns:soapenv="http://shcemas.xnlsoap.org/soap/envelope/"
xmlns:upb="http://127.0.0.1:8888/UPB"
	<soapenv:Header/>
	<soapenv:Body>
		<upb:ReqS00000000001>
			<upb:ReqSysHead>
				<upb:SvcId>?</upb:SvcId>
				<upb:SvcScn>?</upb:SvcScn>
			</upb:ReqSysHead>
		</upb:ReqS00000000001>
	</soapenv:Body>
</soapenv:envelope>

由以上兩圖可見,其他系統提供的服務檔案的名稱空間少了一層【請求類的名稱空間】,而且屬性的名稱空間也不標準

在 http://blog.csdn.net/tangmingxin0529/article/details/79310256 這篇文章中有客戶端程式碼的生成過程介紹。

二:客戶端名稱空間修改

1:請求類的名稱空間修改

Stub類中有webservice服務的呼叫方法,其引數類的類定義處既有請求類的名稱空間設定。

public static class ReqS00000000001 implements
	org.apache.axis2.databinding.ADBBean{
   public static final javax.xml.namespace.QName MY_QNAME=
		new javax.xml.namespace.QName(
		"http://127.0.0.1:8888/UPB","ReqS00000000001","ns1")
	}

從最初的客戶端程式碼可見,請求類的名稱空間為UPB,這裡需要先將其修改為

public static class ReqS00000000001 implements
	org.apache.axis2.databinding.ADBBean{
   public static final javax.xml.namespace.QName MY_QNAME=
		new javax.xml.namespace.QName(
		"http://127.0.0.1:8888/UPB/wsdl","ReqS00000000001","tns")
	}

這樣請求類的名稱空間暫時變成了wsdl,並且名稱空間會由兩個變成3個

2:返回類的名稱空間修改

最初的返回類名稱空間也為UPB,這樣在呼叫服務返回是會報Unexpected subelement RspS00000000001異常

while(!reader.isEndElement()){
	if(reader.isStartElement()){
	if(reader.isStartElement()&& new javax.xml.namespace.QName(
	"http://127.0.0.1:8888/UPB","RspS00000000001").equals(reader.getName())){
	object.setRspS00000000001(RspS00000000001Type.Factory.parse(reader));}
返回類的名稱空間修改並不在其類的定義處修改,而是在
public static class Factory{
	public static RspS00000000001 parse(javax.xml.stream.XMLStreamReader reader){

這個方法中進行修改的,Factory會進行名稱空間的校驗及欄位的校驗

public static class Factory{
	public static RspS00000000001 parse(javax.xml.stream.XMLStreamReader reader){
	......
	while(!reader.isEndElement()){
	if(reader.isStartElement()){
	if(reader.isStartElement()&& new javax.xml.namespace.QName(
	"http://127.0.0.1:8888/UPB/wsdl","RspS00000000001").equals(reader.getName())){
	object.setRspS00000000001(RspS00000000001Type.Factory.parse(reader));}
	......

3:截止目前,請求類和返回類的名稱空間都已經進行了修改,但是這隻能在原有的兩層名稱空間上加上第三個名稱空間,並不是最終的統一樣式

private org.apache.axiom.soap.SOAPEnvelope toEnvelope(
	  org.apache.axiom.soap.SOAPFactory factory,
	  .......ReqS00000000001  param,
	  boolean optimizeContent) throws org.apache.axis2.AxisFault{
	  try{
		org.apache.axiom.soap.SOAPEnvelope emptyEnvelope=factory.getDefaultEnvelope();
		//-------------------手動新增---------------------
		emptyEnvelope.declareNamespace(
			"http://127.0.0.1:8888/UPB/wsdl","tns";
		emptyEnvelope.declareNamespace(
			"http://127.0.0.1:8888/UPB","s"
			);
		//-------------------手動新增---------------------
新增這幾行程式碼之後,所以的名稱空間為wsdl都是轉換成tns,所以屬性的名稱空間upb都會轉換成s。現在即為全系統統一的標準soap報文格式。