概要:
wsdl規範的webservice使用的比較廣泛,尤其是在異構系統中進行數據交換。驗證webserivce的可用性,進而調用webservice的方法,大家都有自己的見解。客戶端調用遵循wsdl規範的遠程webservice服務,發送請求時本質上是http請求,這就爲直接通過發送http請求,調用webservic服務提供了理論基礎。
說說自己的方法。
我們將實際的運行環境,分爲本地和線上
本地,生成客戶端(cxf,jdk自帶工具都可以),進行調用
線上,使用curl發送遵循soap協議的http請求,進行調用。
1、本地驗證
本地驗證,就不重複了,自行搜索。
2、線上環境驗證
線上環境,通常爲linux服務器,當然windows也是可以的,協議是通用的。驗證環境如下
環境配置:
操作系統:linux
附屬工具:curl
2.1 生成SOAP協議格式的報文參數
調用遠程的webservice服務,是通過http請求,就要構造請求參數,下面給出構造過程和結果
構造結果是啥樣子的呢?
包含兩部分,一個是curl的參數,部分是soap報文
整體上類似這樣子
curl -H 'content-type: application/xml' -d '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:curlService xmlns:ns2="http://linghushaoixa.github.io"><request><password>yingying</password><userName>linghushaoxia</userName></request></ns2:curlService></soap:Body></soap:Envelope>' http://ip:port/soap/services/curl_soap_service?wsdl
格式化一下soap的原文,得到清晰的結構
soap協議的簡要結構:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:curlService xmlns:ns2="http://linghushaoixa.github.io">
<request>
<password>yingying</password>
<userName>linghushaoxia</userName>
</request>
</ns2:curlService>
</soap:Body>
</soap:Envelope>
基本說明:
soap:Envelope,報文消息主體聲明
soap:Body,消息體
ns2:curlService,方法
xmlns:ns2,目標命名空間,targetNamespace
request,請求參數,自定義的參數名,由接口的WebParam指定,本例中就命名爲了request,不要照搬,導致錯誤
2.2 封裝爲curl命令
知道了結構,就可以進行封裝了。封裝的結果上圖已經給出,需要的參數,方法名、參數名、參數的值、wsdl地址
代碼如下
package com.linghushaoxia.soap.util;
import java.io.StringWriter;
import com.google.gson.Gson;
import com.thoughtworks.xstream.XStream;
/**
* 功能說明:轉換工具類
* @author: linghushaoxia
* @time:2017年7月3日上午9:35:28
* @version:1.0
*
*/
public class TransformUtil {
/**
*
* 功能說明:將soap協議的報文封裝爲curl命令,以便在linux服務器上執行
* @param url
* wsdl的遠程地址
* 遠程webservice協議的soap報文
* @param soapXml
* @return String
* @time:2017年7月3日上午9:38:59
* @author:linghushaoxia
* @exception:
*
*/
public static String wsdlToCurlWithSoapMsg(String url,String soapXml){
String curl ="";
StringBuilder curlBuilder = new StringBuilder();
curlBuilder.append("curl -H").append(" 'content-type: application/xml'");
curlBuilder.append(" -d ").append("'").append(soapXml).append("'");
curlBuilder.append(" ").append(url);
curl = curlBuilder.toString();
return curl;
}
/**
*
* 功能說明:將webservice接口調用轉爲curl命令,以便在linux服務器上執行
* @param wsdlUrl
* wsdl地址
* @param methodName
* 方法名
* @param webParam
* 參數名,webservice客戶端聲明的名稱
* @param request
* 請求參數,pojo
* @param targetNamespace
* 命名空間
* @return String
* @time:2017年7月3日下午3:03:24
* @author:linghushaoxia
* @exception:
*
*/
public static <T> String wsdlToCurl(String wsdlUrl,String methodName,String webParam,T request,String targetNamespace){
String curl ="";
//封裝爲curl指令
String soapXml = buildSoapXml(methodName,webParam,request,targetNamespace);
curl = wsdlToCurlWithSoapMsg(wsdlUrl, soapXml);
return curl;
}
/**
*
* 功能說明:將請求參數封裝爲soap協議的xml報文
* @param methodName
* 方法名
* @param webParam
* 參數名,webservice客戶端聲明的名稱
* @param param
* 請求參數,pojo
* @param targetNamespace
* 命名空間
* @return String
* @time:2017年7月3日下午4:13:03
* @author:linghushaoxia
* @exception:
*
*/
private static <T> String buildSoapXml(String methodName,String webParam,T param,String targetNamespace){
/**
* 封裝soap協議格式
* 格式從cxf的客戶端報文中截取得到
* 包含四部分
* start-body--method-param
*/
StringBuilder soapBuilder = new StringBuilder();
appendSoapEnvelopeStart(soapBuilder);
appendSoapBodyStart(soapBuilder);
appendSoapMethodStart(soapBuilder,methodName,targetNamespace);
appendSoapParam(soapBuilder,webParam,param);
appendSoapMethodEnd(soapBuilder,methodName);
appendSoapBodyEnd(soapBuilder);
appendSoapEnvelopeEnd(soapBuilder);
return soapBuilder.toString();
}
/**
*
* 功能說明:soap協議聲明,開始
* @param soapBuilder
* @time:2017年7月3日下午6:17:06
* @author:linghushaoxia
* @exception:
*
*/
private static void appendSoapEnvelopeStart(StringBuilder soapBuilder){
soapBuilder.append("<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">");
}
/**
*
* 功能說明:soap協議聲明,結束
* @param soapBuilder
* @time:2017年7月3日下午6:17:29
* @author:linghushaoxia
* @exception:
*
*/
private static void appendSoapEnvelopeEnd(StringBuilder soapBuilder){
soapBuilder.append("</soap:Envelope>");
}
/**
*
* 功能說明:soap協議body,開始
* @param soapBuilder
* @time:2017年7月3日下午6:18:09
* @author:linghushaoxia
* @exception:
*
*/
private static void appendSoapBodyStart(StringBuilder soapBuilder){
soapBuilder.append("<soap:Body>");
}
/**
*
* 功能說明:soap協議body,結束
* @param soapBuilder
* @time:2017年7月3日下午6:18:23
* @author:linghushaoxia
* @exception:
*
*/
private static void appendSoapBodyEnd(StringBuilder soapBuilder){
soapBuilder.append("</soap:Body>");
}
/**
*
* 功能說明:soap協議方法,開始
* @param soapBuilder
* 構建字符串對象
* @param methodName
* 方法名
* @param targetNamespace
* 命名空間
* @time:2017年7月3日下午6:18:42
* @author:linghushaoxia
* @exception:
*
*/
private static void appendSoapMethodStart(StringBuilder soapBuilder,String methodName,String targetNamespace){
soapBuilder.append("<ns2:").append(methodName);
soapBuilder.append(" ").append("xmlns:ns2=\"").append(targetNamespace).append("\"").append(">");
}
/**
*
* 功能說明:soap協議方法,結束
* @param soapBuilder
* @param methodName
* 方法名
* @time:2017年7月3日下午6:19:03
* @author:linghushaoxia
* @exception:
*
*/
private static void appendSoapMethodEnd(StringBuilder soapBuilder,String methodName){
soapBuilder.append("</ns2:").append(methodName).append(">");
}
/**
*
* 功能說明:soap協議,封裝參數
* @param soapBuilder
* @param webParam
* 參數名,webservice客戶端聲明的名稱
* @param param
* 請求參數,pojo
* @time:2017年7月3日下午6:19:21
* @author:linghushaoxia
* @exception:
*
*/
private static <T> void appendSoapParam(StringBuilder soapBuilder,String webParam,T param ){
soapBuilder.append(beanToXml(param,webParam));
}
/**
*
* 功能說明:java對象轉爲xml字符串,XStream
* @param obj
* @return String
* @time:2017年7月3日下午4:03:03
* @author:linghushaoxia
* @exception:
*
*/
private static <T> String beanToXml(T obj,String webParam){
//返回結果
String xmlResult="";
XStream xstream = new XStream( );
//類別名,節點的名稱,默認是全類名
xstream.alias(webParam, obj.getClass());
String xmlFormat= xstream.toXML(obj);
/**
* 取消格式化
*/
xmlResult=xmlFormat.replaceAll("\\s*|\\t|\\r|\\n", "");
return xmlResult;
}
}
以上代碼中幾個關鍵參數,是怎麼得到的?找到客戶端產生的接口,本例爲,ICurlSoapService
如下圖
測試
/**
* 功能說明:curl訪問soap
* @author: linghushaoxia
* @time:2017年7月5日下午12:52:23
* @version:1.0
*
*/
public class CurlSoapServiceDemo {
public static void main(String[] args) {
//wsdl地址
String wsdlUrl="http://ip:port/cesso/services/curl_soap_service?wsdl";
//所要調用的方法名
String methodName="curlService";
/**
* 請求參數
*/
SoapRequest request=new SoapRequest();
request.setUserName("linghushaoxia");
request.setPassword("yingying");
String webParam="request";
//命名空間
String targetNamespace="http://linghushaoixa.github.io";
String curl= TransformUtil.wsdlToCurl(wsdlUrl, methodName, webParam,request, targetNamespace);
System.out.println("curl=");
System.out.println(curl);
}
2.3 調用
登錄到linux服務器,就可以執行了
curl -H 'content-type: application/xml' -d '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:curlService xmlns:ns2="http://linghushaoixa.github.io"><request><password>yingying</password><userName>linghushaoxia</userName></request></ns2:curlService></soap:Body></soap:Envelope>' http://ip:port/cesso/services/curl_soap_service?wsdl
結果如圖
可以看到,返回碼爲10001,msg爲succes。這是服務端返回的結果,返回結果仍然以soap協議的報文給出。
思考:
怎麼得到soap報文的格式呢?這是一個好問題,不同的框架,有不同的方法,歡迎留言討論。參考:
http://blog.csdn.net/russ44/article/details/53308838