webservice客戶端名稱空間
阿新 • • 發佈:2019-01-22
一:開發背景
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報文格式。