一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - Web Service 運行原理詳細介紹

Web Service 運行原理詳細介紹

2020-06-28 11:55java教程網 JAVA教程

這篇文章主要介紹了 Web Service 運行原理詳細介紹的相關資料,需要的朋友可以參考下

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

      Web服務中,我們應該首先了解相關的術語含義:WSDL、UDDI....相關術語方面的介紹在此不再贅述,重點放在原理上。
在Web服務中,存在三個角色:服務提供者、服務請求者和服務中介,三者之間的關系如圖1-1所示

    實現一個完整的Web服務包括以下步驟:

   ◆ Web服務提供者設計實現Web服務,并將調試正確后的Web服務通過Web服務中介者發布,并在UDDI注冊中心注冊; (發布)

   ◆ Web服務請求者向Web服務中介者請求特定的服務,中介者根據請求查詢UDDI注冊中心,為請求者尋找滿足請求的服務; (發現)

   ◆ Web服務中介者向Web服務請求者返回滿足條件的Web服務描述信息,該描述信息用WSDL寫成,各種支持Web服務的機器都能閱讀;(發現)

   ◆ 利用從Web服務中介者返回的描述信息(WSDL)生成相應的SOAP消息,發送給Web服務提供者,以實現Web服務的調用;(綁定)

   ◆ Web服務提供者按SOAP消息執行相應的Web服務,并將服務結果返回給Web服務請求者。(綁定)

   Web Service 運行原理詳細介紹

圖1-1 Web service的體系結構

     注:WSDL的作用就是一個Web服務說明書。服務請求者根據此WSDL生成相應的SOAP消息,服務提供者在收到SOAP請求消息后,進行服務的綁定。

     以下代碼是在web.xml中的servlet配置

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- 在向servlet或JSP頁面制定初始化參數或定制URL時,必須首先命名servlet或JSP頁面。Servlet元素就是用來完成此項任務的。 -->
<servlet>
<servlet-name>UserService</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
<!-- 標記容器是否在啟動的時候就加載這個servlet(實例化并調用其init()方法;正數的值越小,該servlet的優先級越高,應用啟動時就越先加載 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 服務器一般為servlet提供一個缺省的URL:http://host/webAppPrefix/servlet/ServletName。
 但是,常常會更改這個URL,以便servlet可以訪問初始化參數或更容易地處理相對URL。在更改缺省URL時,使用servlet-mapping元素。 -->
<servlet-mapping>
 <servlet-name>UserService</servlet-name>
 <!-- 描述了相對于Web應用的根目錄的URL。url-pattern元素的值必須以斜杠(/)起始。 -->
 <url-pattern>/user</url-pattern>
</servlet-mapping>
紅色代碼部分很重要,會在Web容器啟動的時候加載相應的servlet。綠色部分為該服務的外部接口。以此找到相應的jax-ws.xml文件(如下所示)
<endpoint name="UserPort" implementation="cn.ujn.service.UserService"
  url-pattern="/user">
</endpoint>

    進而綁定到相關的相應的實現類cn.ujn.service.UserService中。客戶端發送的SOAP請求消息消息體body中包含有客戶端所請求的方法名和參數信息。

    以下為客戶端封裝的soap消息體(以Json方式與服務端進行數據傳輸)(SOAP Rerquest Envelope):

?
1
2
3
4
5
6
7
  <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://ujn.cn/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <soapenv:Body>
-  <q0:login>
     <arg0>{"username":"shq","password":"shq"}</arg0>
 </q0:login>
 </soapenv:Body>
 </soapenv:Envelope>

以下為SOAP1.1協議調用Web服務

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/**
* 通過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<String, String> headerParameters,
Map<String, String> bodyParameters, boolean isBodyParametersNS)
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("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" 
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("<soap:Header>");
for (Entry<String, String> headerParameter : headerParameters
.entrySet()) {
sb.append("<ns0:");
sb.append(headerParameter.getKey());
sb.append(">");
sb.append(headerParameter.getValue());
sb.append("</ns0:");
sb.append(headerParameter.getKey());
sb.append(">");
}
sb.append("</soap:Header>");
}
//拼裝消息體
sb.append("<soap:Body><ns0:");
sb.append(method);
sb.append(">");
// 輸入參數
if (bodyParameters != null) {
for (Entry<String, String> inputParameter : bodyParameters
.entrySet()) {
if (isBodyParametersNS) {
sb.append("<ns0:");
sb.append(inputParameter.getKey());
sb.append(">");
sb.append(inputParameter.getValue());
sb.append("</ns0:");
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("</ns0:");
sb.append(method);
sb.append("></soap:Body></soap:Envelope>");
//測試用
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):

?
1
2
3
4
5
6
7
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
-<S:Body>
-<ns2:loginResponse xmlns:ns2="http://ujn.cn/">
 <return>1</return>
</ns2:loginResponse>
 </S:Body>
</S:Envelope>

    客戶端接收到服務端發來的Json數據后會進行相應的解析操作。如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 將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服務的基本工作原理。

    感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲欧美另类综合 | re99| 免费一级欧美大片在线观看 | 九九99热 | 免费看伦理片 | 国产精品吹潮香蕉在线观看 | 亚洲一二三区久久五月天婷婷 | 亚洲香蕉伊在人在线观婷婷 | 暖暖 免费 高清 日本 在线1 | 调教女警花穿环上班 | 成人免费一区二区三区在线观看 | 成人黄色a级片 | 精品国产免费一区二区三区 | 久久re这里精品在线视频7 | 四虎最新免费网址 | 国产区综合另类亚洲欧美 | 日韩在线免费 | 好大好长好紧爽免费 | 袖珍人与大黑人性视频 | 五月婷婷丁香色 | 办公室恋情在线 | 色综合97天天综合网 | 成人免费观看在线视频 | 日本在线观看视频网站 | 日本玖玖视频 | 久见久热 这里只有精品 | 精品国产品香蕉在线观看75 | 国产福利一区二区三区 | 久久久无码精品亚洲A片软件 | 国产成人在线视频 | 亚洲精品一区制服丝袜 | 天天狠天天透天干天天怕处 | 国产成人咱精品视频免费网站 | 亚洲欧美日韩国产精品一区 | 免费观看毛片视频 | 羞羞视频污 | 欧美一区二区三区视视频 | 互换身体全集免费观看 | 超级乱淫伦小说全集np | 粉嫩尤物在线456 | avav男人天堂|