Web Service進階(一)運行原理
利用清明小假期,溫習了一遍Web Service的相關內容,對其工作原理進行了簡要總結。以供有需求的朋友和自己日后參考。文章若有不當之處,敬請朋友們提出寶貴建議,以求共勉。

Web服務中,我們應該首先了解相關的術語含義:WSDL、UDDI....相關術語方面的介紹在此不再贅述,重點放在原理上。
在Web服務中,存在三個角色:服務提供者、服務請求者和服務中介,三者之間的關系如圖1-1所示:(摘錄自:http://www.cnblogs.com/Jessy/p/3528341.html)。
實現一個完整的Web服務包括以下步驟:
◆?Web服務提供者設計實現Web服務,并將調試正確后的Web服務通過Web服務中介者發布,并在UDDI注冊中心注冊;?(發布)
◆?Web服務請求者向Web服務中介者請求特定的服務,中介者根據請求查詢UDDI注冊中心,為請求者尋找滿足請求的服務;?(發現)
◆?Web服務中介者向Web服務請求者返回滿足條件的Web服務描述信息,該描述信息用WSDL寫成,各種支持Web服務的機器都能閱讀;(發現)
◆ 利用從Web服務中介者返回的描述信息(WSDL)生成相應的SOAP消息,發送給Web服務提供者,以實現Web服務的調用;(綁定)
◆?Web服務提供者按SOAP消息執行相應的Web服務,并將服務結果返回給Web服務請求者。(綁定)
圖1-1?Web service的體系結構
注:WSDL的作用就是一個Web服務說明書。服務請求者根據此WSDL生成相應的SOAP消息,服務提供者在收到SOAP請求消息后,
進行服務的綁定。
以下代碼是在web.xml中的servlet配置
紅色代碼部分很重要,會在Web容器啟動的時候加載相應的servlet。綠色部分為該服務的外部接口。以此找到相應的jax-ws.xml文件(如下所示)
url-pattern="/user">
進而綁定到相關的相應的實現類cn.ujn.service.UserService中。客戶端發送的SOAP請求消息消息體body中包含有客戶端所請求的方法名和參數信息。
以下為客戶端封裝的soap消息體(以Json方式與服務端進行數據傳輸)(SOAP Rerquest Envelope):
-? ??
-? ??
以下為SOAP1.1協議調用Web服務
/**
* 通過SOAP1.1協議調用Web服務
*
* text/xml 這是基于soap1.1協議
*
* @param wsdl WSDL路徑
* @param method方法名
* @param namespace命名空間
* @param headerParameters 頭參數
* @param bodyParameters 體參數
* @param isBodyParametersNS 體參數是否有命名空間
* @return String
* @throws Exception
*/
public static String invokeBySoap11(String wsdl, String method,
String namespace, Map
Map
throws Exception {
StringBuffer soapOfResult = null;
// 去除 ?wsdl,獲取方法列表
int length = wsdl.length();
wsdl = wsdl.substring(0, length - 5);
//以字符串為參數創建URL實例
URL url = new URL(wsdl);
//創建連接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//設置請求方式
conn.setRequestMethod("POST");
//如果打算使用 URL連接進行輸入,則將 DoInput 標志設置為 true
conn.setDoInput(true);
//如果打算使用 URL連接進行輸出,則將 DoInput 標志設置為 true
conn.setDoOutput(true);
//主要是設置HttpURLConnection請求頭里面的屬性(K-V)
conn.setRequestProperty("Content-Type", "text/xml;charset=utf-8");
//獲取輸入流(相對于客戶端來說,使用的是OutputStream)
OutputStream out = conn.getOutputStream();
// 獲取soap1.1版本消息
StringBuilder sb = new StringBuilder();
sb.append(" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" "); sb.append("xmlns:ns0=\"" + namespace + "\""); sb.append(">"); //拼裝消息頭 if (headerParameters != null) { sb.append(" for (Entry .entrySet()) { sb.append(" sb.append(headerParameter.getKey()); sb.append(">"); sb.append(headerParameter.getValue()); sb.append(" sb.append(headerParameter.getKey()); sb.append(">"); } sb.append(""); } //拼裝消息體 sb.append(" sb.append(method); sb.append(">"); // 輸入參數 if (bodyParameters != null) { for (Entry .entrySet()) { if (isBodyParametersNS) { sb.append(" sb.append(inputParameter.getKey()); sb.append(">"); sb.append(inputParameter.getValue()); sb.append(" sb.append(inputParameter.getKey()); sb.append(">"); } else { sb.append("<"); sb.append(inputParameter.getKey()); sb.append(">"); sb.append(inputParameter.getValue()); sb.append(""); sb.append(inputParameter.getKey()); sb.append(">"); } } } sb.append(" sb.append(method); sb.append(">
//測試用
System.out.println(sb.toString());
//寫入SOAP消息(相對于客戶端來說,使用的是out.write())
out.write(sb.toString().getBytes());
//獲取服務器端的相應
int code = conn.getResponseCode();
if (code == 200) {
InputStream is = conn.getInputStream();
byte[] b = new byte[1024];
int len = 0;
soapOfResult = new StringBuffer();
//從輸入流中讀取一定數量的字節,并將其存儲在緩沖區數組 b 中。以整數形式返回實際讀取的字節數
//如果因為流位于文件末尾而沒有可用的字節,則返回值 -1;
while ((len = is.read(b)) != -1) {
//Converts the byte array to a string using the named charset.
String s = new String(b, 0, len, "UTF-8");
soapOfResult.append(s);
}
}
conn.disconnect();
return soapOfResult == null ? null : soapOfResult.toString();
}
注:在客戶端發送SOAP請求消息后便處于阻塞狀態。直至服務端返回狀態碼。
以下為服務端進行響應(SOAP Response Envelope):
-
-
客戶端接收到服務端發來的Json數據后會進行相應的解析操作。如下:
// 將Soap協議進行解析(DOM解析只能用于解析XML文檔類型,而SOAP消息就是采用XML數據格式)
Document doc = XmlUtil.string2Doc(result);
Element ele = (Element) doc.getElementsByTagName("return").item(0);
方法中使用到的string2Doc()方法體如下:
public static Document string2Doc(String str) {
//將XML文檔解析成DOM樹
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document document = null;
DocumentBuilder build;
if (str == null || str.equals("")) {
return null;
}
try {
InputStream bais = new ByteArrayInputStream(str.getBytes("UTF-8"));
build = factory.newDocumentBuilder();
//Parse the content of the given InputStream as an XML document and return a new DOM Document object.
document = build.parse(bais);
} catch (Exception e) {
e.printStackTrace();
}
return document;
}
根據返回結果,客戶端再進行相應的處理。
以上是web服務的基本工作原理。在此感謝實驗室徐師兄的技術支持。
web前端 XML
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。