<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 19, 文章 - 93, 評論 - 17, 引用 - 0
    數據加載中……

    在面向服務的體系結構中管理狀態

    ??????一個有關 Web 服務的最常見誤解是,它們只適合于支持基于同步請求/響應 SOAP(簡單對象訪問協議)的交互。 造成這種誤解的主要原因之一是,許多 Web 服務是使用不可靠的無狀態傳輸協議(如 HTTP)實現的。

      因此,許多組織正避免用 Web 服務來處理復雜的業務交互(在復雜業務交互中,服務使用者可能同時與同一服務進行多個交互,或同時與多個服務進行多個交互)。 OASIS(結構化信息標準促進組織)將此類交互稱作 Web 服務會話,并將支持會話的 Web 服務稱作會話式 Web 服務。 會話式 Web 服務是異步 Web 服務的基礎,在實現持續長時間業務事務方面起著至關重要的作用。

      本文將介紹如何使用顯式狀態標識符支持會話式 Web 服務。 此外,還將概述如何使用 Oracle JDeveloper 10g 10.1.3 J2EE 開發人員預覽版(為 J2EE 1.4 JAX-RPC 提供了內置的支持)實現該種方法。

      會話式 Web 服務簡介

      服務使用者與服務提供者之間的大多數交互是 Web 服務會話,例如,某個服務端點可能同時從多個客戶端收到多種類型的文檔,處理這些文檔并使用相應的響應聯系使用者。 在這樣的應用程序中,特別要求正確識別每個客戶端的交互,這使得 Web 服務實現更加復雜。 為了避免這種復雜性,許多公司將 Web 服務實現局限于簡單的單一請求/響應類型的交互(AuthorizeUser、CalculateTax、ConvertFunds 等)。

      但就其理想情形而言,Web 服務應支持服務使用者和支持提供者之間的單一交互和復雜交互。 無論傳輸協議如何,同步或異步 Web 服務都應能夠代表單個客戶端或在跨多個交互的特殊業務環境中保存狀態或資源。

      長期以來,解決 Web 服務中的狀態性問題的需要一直是標準組織和主要供應商的焦點。 為解決關鍵任務和冗長業務流程中的狀態性問題,涌現了多個 Web 服務規范草案,如 WS-Addressing、WS-Resources 和 WS-Coordination。 最重要的是,業務流程執行語言 (BPEL) 1.0 規范已經整合了 WS-* 標準建議的許多特性來處理持續時間較長的業務事務。 但也應看到新標準和解決 Web 服務會話問題的相關供應商技術的廣泛采用。

      總之,實現會話式 Web 服務仍是一個相當大的設計挑戰。 當面臨依賴 Web 服務的復雜應用程序時,應用程序開發人員別無選擇,只能構建定制的解決方案。

      會話式 Web 服務的工作方式

      會話式 Web 服務(本質上是異步的)有兩個重要的服務元素類型: 可調用方法和響應方法(通常稱作回調)。 會話式 Web 服務中的每個可調用方法和回調方法確定該服務、其客戶端以及該服務所使用的任何執行控件(例如,Java 控件)之間的通信行為。 可調用方法可以啟動、繼續或結束會話;而回調可以繼續或停止會話。

      為更好地描述會話式 Web 服務,我將介紹一個場景,在本文通篇將以該場景為基礎。 該示例采用兩個會話: 一個是 Web 服務與它的客戶端之間的會話,另一個是兩個 Web 服務之間的會話(參見圖 1)。

      在本示例中,BestTermInsurance Web 服務通過使用另一個服務 (InsuranceQuote) 代表客戶查找各種保險提供商 。 當客戶端請求 BestTermInsurance 服務提供報價時,將啟動第一個會話;當 BestTermInsurance 服務調用 InsuranceQuote 服務請求報價時,將啟動第二個會話。 當 InsuranceQuote 服務找到最低報價時,它將響應 BestTermInsurance 服務,第二個會話隨即完成。 然后,BestTermInsurance 服務恢復與客戶端的第一個會話。



    圖 1: BestTermInsurance 服務

      Web 服務會話保存 Web 服務的狀態;后者包括用于鏈接 Web 服務、它的客戶端和其他資源之間的通信的相關數據以及在會話完成之前由該服務保存的任何數據。 該狀態信息稱作會話狀態(也稱作關聯狀態)。 在本示例中,BestTermInsurance 服務保存客戶端的每個報價以及關聯的消息屬性,直到找到最低報價。

    管理會話狀態

      使用顯式狀態標識符是在 Web 服務交互中管理會話狀態的最簡單和最相當有效的方法。 盡管名稱暗示了單個 ID,但完全受管理的會話需要更多的信息,尤其是當與服務請求關聯時。 因此,狀態標識符實際上是一個控制類,它保存以下一組針對每個請求-響應交互的與狀態相關的信息:

    •   Web 服務客戶端的唯一標識符
    •   為該客戶端啟動的 Web 服務會話的標識符
    •   該會話中服務請求的標識符
    •   服務請求者(客戶端)與服務提供者之間的會話階段指示器,服務使用該指示器進行正確的狀態保持
    •   Web 服務基礎架構的分發函數與調用接口之間的交互狀態指示器(在使用 Web 服務接口的晚期綁定進行動態調用方面很有幫助)

      出于本文的需要,我采用靜態 Web 服務調用,因此將不介紹第 5 種信息。

      一般說來,用于關聯請求的技術解決方案是讓服務請求者將狀態標識符信息(服務請求的唯一標識符(請求 ID)、會話標識符(會話 ID)和會話階段指示器(階段)添加到請求消息中,并讓服務提供者將標識符信息復制到通過回調傳遞的響應消息中,這樣請求者可以將回復消息與請求消息相關聯。

      有多種方法可以將狀態標識符信息包含在消息交換中,具體包括:

    •   將標識符信息以額外的參數形式傳入 Web 服務方法;可以將 Web 服務接口設計為不但接受 XML 文檔消息,而且接受其他代表狀態標識符信息的參數。
    •   將標識符信息作為 XML 文檔的一部分傳遞 — XML 文檔可以包嵌在其主體中的此種信息。
    •   在 SOAP 消息標頭中傳遞標識符信息。

      但無論是通過添加額外的輸入參數將標識符信息包含在服務接口中的第一種方法,還是將此類信息包含在 XML 文檔本身中的第二種方法,事實上都會使標識符信息處理成為服務結構一部分,從而使代碼更難以維護。 此外,將來隨著新 Web 服務標準被更廣泛地接受,可能不再需要自定義解決方案了,從而將難以從服務實現中“拆除”嵌入的、與標識符相關的邏輯。

      因此,第三種方法,即將標識符信息包含在 SOAP 消息標頭中是最合理的方法。 使用此方法時,服務請求者將標識符信息作為一組新的子元素添加到消息的 SOAP 標頭中。 服務提供者攔截該 SOAP 消息,然后提取標頭中相應的狀態標識符信息且不會破壞消息主體。

      簡單地說,將標識符信息添加到 SOAP 標頭中將使相關的代碼與文檔處理邏輯和關聯的業務邏輯以及服務接口的具體實現相分離。

      實現顯式的狀態標識符 - 示例

      現在,我們將繼續介紹示例場景 - BestTermInsurance 服務。 (請參見圖 2 以獲得該場景的說明。) 正如邊條中描述的,Oracle 應用服務器提供了兩個服務實現選項: 無狀態 Java 類(可以部署到 Web 容器中)或無狀態會話 EJB。 (該設計基于將 EJB 與一個服務 fa ade — BestTermInsuranceServlet 一起使用)。 建議您使用 fa?ade 將服務實現為 EJB,這是因為這樣做不但具有更好的服務可用性和可伸縮性,還可以引入 SOAP JAX-RPC 處理程序(稍后將對其進行詳細介紹)。


    圖 2: 示例場景

      下面我們將逐步介紹此示例場景并了解該控件。 當客戶端通過調用 servlet 的 requestQuote 方法(傳遞有關客戶年齡和健康狀況的信息)提交搜索請求時,Web 服務交互將啟動。 requestQuote() 方法包含一個 void 返回值,并立即返回,從而使客戶端可以繼續操作,而不必等待稍后將通過 onBestQuote() 回調發送的實際結果。 顯而易見,應將客戶端設計為從回調方法中接受消息。

    ??????接下來,BestTermInsuranceServlet 調用 BestTermInsuranceEJB(用于保存客戶年齡和健康狀況指示器)和一個所獲得的報價列表(與客戶端 ID 和請求 ID 關聯,作為與狀態相關的數據)。 BestTermInsuranceEJB 隨后調用 InsuranceQuote 服務的 obtainQuote() 方法以從參與的保險人那里獲得報價。 (參見圖 3,一個演示最重要的服務交互的序列圖。)


    圖 3: 使用 JDeveloper Modeler 的示例 UML 序列圖

      InsuranceQuote 服務在特定客戶端作用域內運行,因此該服務需要訪問客戶端 ID。在會話跟蹤方面,InsuranceQuote 服務使用它自己的會話和請求 ID。

      在根據給定的客戶年齡和健康狀況指示器收集所有保險報價時,InsuranceQuote 服務使用 onObtainQuoteComplete() 回調返回其結果。 此回調完成第二個轉換,并清除由 InsuranceQuote 服務保存的所有狀態數據。 但由 BestInsuranceQuoteServlet 控制的第一個會話仍繼續執行: BestTermInsurance 服務可能從客戶端獲取其他請求,例如,根據特殊的保單條款(一年、十年等)提供最佳報價。 結果以消息形式通過 onBestQuoteCallback() 方法發送給客戶端。

      編碼技巧

      現在,我們來著重介紹以下實現狀態標識符的具體編碼技巧。 遺憾地是,由于篇幅有限,將只在代碼中介紹與本文主題相關的元素。

      正如前面所介紹的,假設狀態標識符信息已傳入 SOAP 消息標頭中。 用于基于 XML 的遠程過程調用的 Java API (JAX-RPC) 非常適于處理 SOAP 消息標頭 - 具體而言就是通過使用 JAX-RPC 的某個最有意義的特性: 消息處理程序。 消息處理程序為 Web 服務提供了附加的消息處理邏輯,以作為對這些服務的業務邏輯實現的擴展。 除了管理身份驗證、加密和解密、日志記錄和審計等外,處理程序還支持狀態標識符的插入。 為此,可以創建多個處理程序來管理每個具體問題。 在 JAX-RPC 中,處理程序的這種用法稱作處理程序鏈。

      處理程序鏈表示一組有序的處理程序。 使用有序組可以使應用程序開發人員能夠定義處理程序調用策略 - 調用順序、目標(“僅處理請求”或“僅處理響應”或兩者都處理)等。 處理程序鏈繼續處理處理程序,直到引發 SOAP 錯誤或調用策略指示顯式停止點。

      因此,要使用 SOAP 標頭內嵌的狀態標識符實現 Web 服務,建議用三個步驟來進行開發:

    •   設計基本的服務組件并進行編碼。
    •   開發 SOAP 消息處理程序。
    •   用已開發的 J2EE 組件構造 Web 服務(公開)。

      使用 Oracle JDeveloper 10g J2EE 開發人員預覽版時,可以使用應用程序導航器下的類別“Business Tier”將已編譯的 Java 類或 bean 公開為 Web 服務。 從該類別中,開發人員可以選擇一個上下文菜單項“Java Web services”。 此菜單項包含兩個選項“J2EE 1.4 (JAX-RPC) Web services”和“Oracle J2EE 1.3 Web services”。 選擇“J2EE 1.4 (JAX-RPC) Web services”。
     以下代碼清單顯示了一個符合要求的 SOAP 消息格式,其中的標頭包含 BestTermInsurance 服務的外部(客戶端-服務)會話的狀態標識符:

    <SOAP-ENV:Envelope>
    ? <SOAP-ENV:Header>
    ????????? <ns:stateIdentifier xmlns:ns="http://xxxxx">
    ????? <ns:ClientID>Client ID</ns:ClientID>
    ????? <ns:ConversationID>Conversation ID</ns:ConversationID>
    ????? <ns:RequestID>Request ID</ns:Request ID>
    ????? <ns:Phase>Phase</ns:Phase>
    </stateIdentifier
    </SOAP-ENV:Header>
    <SOAP-ENV:Body>
    ???? <ns:insuranceParms xmlns:ns="http://yyyyyyy">
    ???? <ns:Age>Age</ns:Age>
    ???? <ns:Health>Health</ns:Health>
    ???? <ns:Term>Term</ns:Term>
    ???? </ns:insuranceParms
    </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>

    但在此進程的開頭,該 SOAP 消息定義不包含狀態標識符信息,如下所示:
    <SOAP-ENV:Envelope>
    ? <SOAP-ENV:Header>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body>
    ???? <ns:insuranceParms xmlns:ns="http://yyyyyyy">
    ???? <ns:Age>Age</ns:Age>
    ???? <ns:Health>Health</ns:Health>
    ???? <ns:Term>Term</ns:Term>
    ???? </ns:insuranceParms
    </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    這正是 SOAP 處理程序的用途所在: 對將狀態限定符插入到標準 SOAP 消息定義進行處理。 在 JAX-RPC 服務中,處理程序由實現 handleRequest() 和 handleResponse() 方法(用于修改請求和響應消息)的處理程序類表示。 可以將處理程序類配置為在客戶端或服務級別處理請求和響應。 處理程序使用 javax.xml.soap.SOAPMessage 類來處理 SOAP 消息。 SOAPMessage 對象包含一個 SOAPPart 對象,該對象包含實際的 SOAP XML 文檔和一個被分解為訪問 SOAP 主體和標頭的 SOAPEnvelope 對象。

      以下代碼清單演示了所描述的方法:

    package exp.oracle.jaxrrpc.headers;

    .............

    import javax.xml.rpc.*;
    import javax.xml.soap.*;

    public class BestTermInsuranceRequestHandler implements javax.xml.rpc.handler.Handler
    {

    ...........................

    ?/*
    ?*The handleRequest method processes the request message.
    ? */
    try {
    SOAPMessageContext msg = (SOAPMessageContext) context;
    SOAPEnvelope env = msg.getMessage().getSOAPPart().getEnvelope();
    SOAPHeader hdr = env.getHeader();
    exit=processRequestHeader(hdr);

    ?????? }
    catch (Exception ex) {
    ex.printStackTrace();
    ?}

    ?return exit;
    ?}


    ?/*
    ?* This version of the process header method inserts the state identifier information.
    ?*/
    ? private boolean processRequestHeader (SOAPHeader hdr) {
    ? boolean exit = false;
    ?
    ? SOAPFactory sFactory = SOAPFactory.newInstance();?
    try {
    SOAPElement he1 = sFactory.createElement("stateIdentifier",PREFIX,URI);
    SOAPElement che11 = sFactory.createElement("ClientID",PREFIX,URI);
    ??????????? che11.addTextNode("Cust1");
    ??????????? ...............................?
    ??????????? he1.addChildElement(che11);
    ??????????? he1.addChildElement(che12);
    ??????????? he1.addChildElement(che13);
    ???????????
    ??????????? // add the state identifier information to the SOAP header object
    ??????????? hdr.addChildElement(he1);
    ??????????? exit = true;??????

    ?????? }
    ?catch (Exception ex) {
    ???? ex.printStackTrace();
    ?}

    ?return exit;
    ??? }
    開發 SOAP 處理程序后,可以使用 WSA 在相應的 webservices.xml 文件中配置它們。 然后,可以繼續創建部署描述文件并將 Web 服務安裝到 OC4J 中。

      結論

      顯而易見,將單個請求-響應交互與無狀態的 Web 服務結合使用是最簡單的實現方法。 但伴隨簡單性而來的是一個很大的缺點: 無法實現用于處理復雜和長期運行的業務事務的 Web 服務。

      本文介紹的狀態管理方法所基于的策略以更出色的方法對長期運行的業務活動進行建模。 具體而言,在本方法中,服務“注冊”到良好控制的會話(將特定的工作單元表示為業務活動進度)。 此功能對于連接企業內部以及跨企業的、支持 Web 服務的應用程序很重要,并包含一組支持對連接的應用程序之間的交互進行管理和監控的特性。


    http://www.oracle.com/technology/global/cn/pub/articles/davydov_soa.html

    posted on 2006-12-02 13:09 BPM 閱讀(263) 評論(0)  編輯  收藏 所屬分類: web services

    主站蜘蛛池模板: 日韩亚洲一区二区三区| 亚洲欧美国产精品专区久久| xxxxxx日本处大片免费看| 亚洲av中文无码乱人伦在线播放 | 国产区在线免费观看| 少妇中文字幕乱码亚洲影视| 女人张开腿给人桶免费视频| 一级黄色免费大片| 亚洲三级在线视频| 国产午夜亚洲精品理论片不卡 | 亚洲国产成人精品电影| 无码专区一va亚洲v专区在线| 抽搐一进一出gif免费视频| 亚洲va久久久噜噜噜久久| 成人免费无毒在线观看网站| 国产无遮挡又黄又爽免费网站| 国产日本亚洲一区二区三区 | 亚洲偷偷自拍高清| 亚洲日韩精品A∨片无码| 夫妻免费无码V看片| 色播在线永久免费视频网站| 亚洲精品国产av成拍色拍| 亚洲第一成年男人的天堂| 亚洲av成人一区二区三区在线观看| 亚洲免费在线视频观看| 中文字幕免费在线看| 色欲色欲天天天www亚洲伊| 亚洲欧洲国产综合| 亚洲精品国产精品乱码视色| 国内自产拍自a免费毛片| 日本免费网站视频www区| 韩国免费a级作爱片无码| 精品国产日韩亚洲一区在线| 亚洲欧洲国产经精品香蕉网| 久久精品亚洲综合专区| 亚洲国产婷婷综合在线精品| 日本二区免费一片黄2019| 中文字幕无码不卡免费视频| 免费国产污网站在线观看15| 国产成人高清精品免费观看| 国产精品亚洲一区二区三区在线观看|