国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

Web Service 運行原理詳細介紹

2019-11-26 13:38:47
字體:
來源:轉載
供稿:網友

     利用清明小假期,溫習了一遍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服務請求者。(綁定)

  

圖1-1 Web service的體系結構

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

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

  <!-- 在向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):

  <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服務

/** * 通過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):

<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數據后會進行相應的解析操作。如下:

// 將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服務的基本工作原理。

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 新疆| 乌鲁木齐市| 沂南县| 十堰市| 渭源县| 腾冲县| 临夏市| 珲春市| 淳安县| 辽宁省| 青海省| 汤阴县| 阿拉善盟| 玉山县| 青川县| 莱芜市| 工布江达县| 建湖县| 建水县| 加查县| 新民市| 武穴市| 昭通市| 尉犁县| 邹城市| 甘孜县| 湘西| 永清县| 惠州市| 昌都县| 德昌县| 广水市| 杭锦后旗| 吉安县| 佛冈县| 平谷区| 永定县| 开平市| 青海省| 乌恰县| 两当县|