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

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

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

    精彩的人生

    好好工作,好好生活

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      147 Posts :: 0 Stories :: 250 Comments :: 0 Trackbacks
    即使 SOAP 只是眾多訪問 Web 服務的可能的綁定之一,它已幾乎成為 Web 服務的同義詞。這意味著使用 Web 服務的應用程序通常通過綁到 SOAP 的特定實現的 API 來完成工作。本系列文章將描述一個更通用的、獨立于 SOAP 的調用 Web 服務的方法,稱之為“Web 服務調用框架”(Web Service Invocation Framework(WSIF))。它專門設計來直接調用用“Web 服務描述語言”(Web Services Description Language(WSDL))描述的 Web 服務,隱藏了底層訪問協議(比如 SOAP)的復雜性。

    Web 服務承諾為因特網分布式計算提供基于標準的平臺,集中在簡易性和靈活性。一種關鍵的 Web 服務技術是 WSDL,即“Web 服務描述語言”。使用 WSDL,開發者可以以抽象的形式描述 Web 服務,與用在其它分布式計算框架(比如 CORBA)的現有“接口描述語言”(Interface Description Language(IDL))類似。WSDL 也使 Web 服務開發者能夠給服務指定具體的綁定。并且這些綁定描述怎樣將抽象服務描述映射到特定訪問協議。WSDL 的這部分是可擴展的,這就是說任何人都可以提出他們自己的綁定,使之可能通過某個定制的協議訪問服務。

    因此,從某種程度來說,使用 Web 服務是一種挑戰。對于同樣的服務可以有多個綁定。這些綁定中的一些可能適合于一些情形,其它可能適合于另外的情形。綁定本身可以代表抽象服務描述到用來訪問服務的任意一種協議的映射。雖然有多種選擇使用服務和允許綁定擴展是很有用的,但這給客戶機以統一方式查看服務造成了困難。

    我以當前客戶機端 API 及其性能的討論開始這篇文章。我將通過討論來激發人們對 WSIF,即“Web 服務調用框架”的需要,然后繼續進行 WSIF 的概述。

    當前的調用風格及其缺點
    用于 Web 服務的 SOAP 綁定是 WSDL 規范的一部分。在大多數編程語言中,該協議有可用的實現和工具,在許多情況下是免費的。這樣,它使得開發者能以微乎其微的成本進行用于 Web 服務的獨立于平臺的開發。

    因此,下述情況是不足為奇的:大多數開發者當想到使用 Web 服務時,在他們頭腦中出現的是使用某個 SOAP 客戶機 API 來裝配一個 SOAP 消息并將它經由網絡發送到服務端點。例如,使用 Apache SOAP,客戶機將創建和植入一個 Call 對象。它封裝了服務端點、要調用的 SOAP 操作的標識、必須發送的參數等等。而這是對 SOAP 而言,它僅限于將其用作調用 Web 服務的一般模型,這是因為下面的原因:

    • Web 服務不僅僅是 SOAP 服務
      將 Web 服務視為 SOAP 上提供的服務的同義詞。這是對 Web 服務狹隘的見解。帶有功能方面和訪問協議 WSDL 描述的任何一段代碼均可以被認為是 Web 服務。WSDL 規范為 Web 服務定義了 SOAP 綁定,但是原則上可能要添加綁定擴展,這樣,例如,使用 RMI/IIOP 作為訪問協議,EJB 就可以作為 Web 服務來提供。或者您甚至可以想象任意一個 Java 類可以被當作 Web 服務,以本機 Java 調用作為訪問協議。就這個更廣闊的 Web 服務定義來說,您需要用于服務調用的獨立于綁定的機制。
    • 將客戶機代碼綁到一個特殊的協議實現要受到限制
      將客戶機代碼緊密地綁定到特殊的協議實現的客戶機庫造成了難以維護的代碼。讓我們假設您在客戶機端有一個用 Apache SOAP v2.1 調用 Web 服務的應用程序。如果您想利用 v2.2 中出現的新的功能和錯誤修正,您將不得不更新所有的客戶機代碼,這是一項耗時的任務,將涉及到常見的令人頭痛的遷移問題。類似的,如果您想從 Apache SOAP 移到一個不同的 SOAP 實現,這個過程并非無關緊要。所需要的是用于服務調用的獨立于協議實現的機制。
    • 將新的綁定融入到客戶機代碼是很困難的。
      WSDL 允許有定義新的綁定的可擴展性元素。這使開發者能夠定義綁定,這種綁定允許使用某種定制協議的代碼作為 Web 服務。但是,事實上實現起來是很困難的。將不得不設計使用該協議的客戶機 API 。應用程序本身可能正是使用 Web 服務的抽象接口,因此將必須編寫一些工具來生成啟用抽象層的存根。這些又一次是并非無關緊要的而且耗時的任務。所需要的是使綁定能夠被更新或新的綁定能夠容易地插入的服務調用機制。
    • 可以以靈活的方式使用多綁定
      例如,設想您已經成功地部署了一個應用程序,該應用程序使用提供多綁定的 Web 服務。為了使這個示例更具體,假設您有用于服務的 SOAP 綁定和允許您將本地服務實現(一個 Java 類)作為 Web 服務的本地 Java 綁定。顯而易見,如果客戶機部署在與服務本身相同的環境中,只能使用面向服務的本地 Java 綁定,并且如果情況確實如此,通過直接進行 Java 調用而不是使用 SOAP 綁定與服務進行通信將高效得多。Java 綁定作為一種快捷訪問機制。接下來,想要利用多綁定可用性的客戶機將必須具有一種能力 — 根據運行時信息對要用的實際綁定進行切換的能力。因此為了利用提供多綁定的 Web 服務,您需要一種服務調用機制,允許您在運行時在可用的服務綁定之間進行切換,而不需要生成或重編譯存根。

    介紹 WSIF
    “Web 服務調用框架”(WSIF)是為調用 Web 服務提供簡單 API 的工具箱,而不管服務怎樣提供或由哪里提供。它具有上面討論中我確定的所有功能:

    • 有給任何 Web 服務提供獨立于綁定訪問的 API。
    • 提供端口類型編譯器來生成允許使用抽象服務接口的調用的存根。
    • 允許無存根(完全動態)的 Web 服務調用。
    • 可以在運行時將更新的綁定實現插入到 WSIF。
    • 可以在運行時插入的新的綁定。
    • 允許將綁定選擇延后到運行時。

    分析 WSIF 的客戶機 API
    為了進行討論,我將使用很常見的股票報價程序 — Web 服務的“Hello World”示例。請考慮下面清單 1 所示的使用 WSDL 的抽象服務描述。

    清單 1:股票報價 Web 服務的 WSDL 描述

    <?xml?version="1.0"??>?
    <definitions?targetNamespace="http://www.ibm.com/namespace/wsif/samples/stockquote-interface"?
    ?????????????xmlns:tns
    ="http://www.ibm.com/namespace/wsif/samples/stockquote-interface"?
    ?????????????xmlns:xsd
    ="http://www.w3.org/1999/XMLSchema"?
    ?????????????xmlns
    ="http://schemas.xmlsoap.org/wsdl/">?
    ??
    <message?name="GetQuoteInput">?
    ????
    <part?name="symbol"?type="xsd:string"/>?
    ??
    </message>?
    ??
    <message?name="GetQuoteOutput">?
    ????
    <part?name="quote"?type="xsd:float"/>?
    ??
    </message>?
    ??
    <portType?name="StockquotePT">?
    ????
    <operation?name="getQuote">?
    ??????
    <input?message="tns:GetQuoteInput"/>?
    ??????
    <output?message="tns:GetQuoteOutput"/>?
    ????
    </operation>?
    ??
    </portType>?
    </definitions>


    足夠簡單:它描述了只帶有由一個端口類型提供一個操作的服務。該操作等待一個字符串,被解釋為股票的報價機符號,然后返回當前該股票報價,一個浮點值。為了實際使用該服務,您需要某個定義訪問機制的綁定以及該綁定的服務端點。清單 2 展示了該服務的 SOAP 綁定:

    清單 2:股票報價 Web 服務的 SOAP 綁定

    <?xml?version="1.0"??>?
    <definitions?targetNamespace="http://www.ibm.com/namespace/wsif/samples/stockquote"?
    ?????????????xmlns:tns
    ="http://www.ibm.com/namespace/wsif/samples/stockquote"?
    ?????????????xmlns:tns-int
    ="http://www.ibm.com/namespace/wsif/samples/stockquote-interface"?
    ?????????????xmlns:xsd
    ="http://www.w3.org/1999/XMLSchema"?
    ?????????????xmlns:soap
    ="http://schemas.xmlsoap.org/wsdl/soap/"?
    ?????????????xmlns:java
    ="http://schemas.xmlsoap.org/wsdl/java/"?
    ?????????????xmlns
    ="http://schemas.xmlsoap.org/wsdl/">?
    ??
    <import?namespace="http://www.ibm.com/namespace/wsif/samples/stockquote-interface"?
    ??????????location
    ="stockquote-interface.wsdl"/>?
    ??
    <binding?name="SOAPBinding"?type="tns-int:StockquotePT">?
    ????
    <soap:binding?style="rpc"?transport="http://schemas.xmlsoap.org/soap/http"/>?
    ????
    <operation?name="getQuote">?
    ??????
    <soap:operation?soapAction="http://example.com/GetTradePrice"/>?
    ??????
    <input>?
    ????????
    <soap:body?use="encoded"?
    ???????????????????namespace
    ="urn:xmltoday-delayed-quotes"?
    ???????????????????encodingStyle
    ="http://schemas.xmlsoap.org/soap/encoding/"/>?
    ??????
    </input>?
    ??????
    <output>?
    ????????
    <soap:body?use="encoded"?
    ???????????????????namespace
    ="urn:xmltoday-delayed-quotes"?
    ???????????????????encodingStyle
    ="http://schemas.xmlsoap.org/soap/encoding/"/>?
    ??????
    </output>?
    ????
    </operation>?
    ??
    </binding>?
    ??
    <service?name="StockquoteService">?
    ????
    <documentation>Stock?quote?service</documentation>?
    ????
    <port?name="SOAPPort"?binding="tns:SOAPBinding">?
    ??????
    <soap:address?location="http://localhost:8080/soap/servlet/rpcrouter"/>?
    ????
    </port>?
    ??
    </service>?
    </definitions>

    這是一個標準的 SOAP 綁定,使用 RPC 風格和作為傳輸協議的 HTTP 與服務進行通信。在文檔的 port 部分中,我定義了使用 SOAP 綁定可以訪問服務的 URI。在清單 3 中,我將就通過 Apache SOAP 2.2 客戶機端 API 和 WSIF 的客戶機 API 使用該服務進行對比。

    清單 3:用于服務訪問的 Apache SOAP API 與 WSIF API 對比

    Apache SOAP API

    //?Step?1:?identify?the?service?
    ?Call?call?=?new?Call();?
    ?call.setTargetObjectURI(
    "urn:xmltoday-delayed-quotes");?
    ?
    //?Step?2:?identify?the?operation?
    ?call.setMethodName("getQuote");?
    ?call.setEncodingStyleURI(encodingStyleURI);?
    ?
    //?Step?3:?identify?the?parameters?
    ?Vector?params?=?new?Vector();?
    ?params.addElement(
    new?Parameter("symbol",?
    ??????????????????????????String.
    class,?symbol,?null));
    ?call.setParams(params);?
    ?
    //?Step?4:?execute?the?operation?
    ?Response?resp?=?call.invoke(url,?
    ???????????????????
    "http://example.com/GetTradePrice");
    ?
    //?Step?5:?extract?the?result?or?fault?
    ?if(resp.generatedFault())?
    ?
    {?
    ???Fault?fault?
    =?resp.getFault();?
    ???System.out.println(
    "Ouch,?the?call?failed:?");?
    ???System.out.println(
    "??Fault?Code???=?"?+??
    ??????????????????????fault.getFaultCode());?
    ???System.out.println(
    "??Fault?String?=?"?+??
    ??????????????????????fault.getFaultString());?
    ???
    throw?new?SOAPException("Execution?failed?"?+?fault);?
    ?}
    ?
    ?
    else?
    ?
    {?
    ???Parameter?result?
    =?resp.getReturnValue();?
    ???
    return?((Float)?result.getValue()).floatValue();?
    ?}


    WSIF API

    //?Step?1:?identify?the?service?
    ?Definition?def?=?WSIFUtils.readWSDL(null,wsdlLocation);
    ?
    //?Step?2:?identify?the?operation?(choose?an?
    ?
    //?appropriate?service?port)?
    ?WSIFDynamicPortFactory?portFactory?=?
    ????????
    new??WSIFDynamicPortFactory(def,?null,?null);?
    ?
    //?Get?default?port?
    ?WSIFPort?port?=?portFactory.getPort();?
    ?
    //?The?user?can?also?explicitly?select?a?port??
    ?
    //?to?use.?
    ?
    //?WSIFPort?port?=??
    ?
    //?????????????portFactory.getPort("SOAPPort");?
    ?
    //?Step?3:?identify?the?parameters?
    ?
    //?Prepare?the?input?message?
    ?WSIFMessage?input?=?port.createInputMessage();?
    ?input.setPart(
    "symbol",??
    ???????????????
    new?WSIFJavaPart(String.class,?symbol));
    ?
    //?Prepare?a?placeholder?for?the?output?value?
    ?WSIFMessage?output?=?port.createOutputMessage();?
    ?
    //?Step?4:?execute?the?operation?
    ?port.executeRequestResponseOperation("getQuote",?
    ?????????????????????????????input,?output,?
    null);
    ?
    //?Step?5:?extract?the?result?or?fault?
    ?WSIFPart?part?=?output.getPart("quote");?
    ?
    return?((Float)part.getJavaValue()).floatValue();


    正如您可以看到的,WSIF 的 API 由以 WSDL 編寫的抽象服務描述驅動;它完全從實際使用的綁定中分離出來。該調用 API 是面向 WSDL 的,并且使用它更自然,因為它使用 WSDL 術語引用消息部件(message part)、操作等等。當您閱讀一個 WSDL 描述,出于直覺會想到選用支持所需端口類型的端口,然后通過提供必需抽象輸入消息(由必要部件組成)調用操作(不用擔心怎樣將消息映射到特定的綁定協議);WSIF API 就是這樣設計的。

    常用的 API,比如上面所示的 Apache SOAP API 采用了以特殊協議為中心的概念,比如在使用 SOAP 的情況下,目標 URI 和編碼風格。這是不可避免的,因為 API 不是普遍適用于 WSDL,而是為特殊的協議設計。

    兩種使用 WSIF 的調用模型
    WSIF 允許 Web 服務以兩種方式調用。一種是無存根的動態調用,它要求直接使用 WSIF API;另一種是通過生成允許應用程序使用 Java 接口(直接對應于 WSDL 端口類型)和隱藏了 WSIF API 的存根的調用。

    無存根(動態的)調用
    訪問 Web 服務所需的所有信息 — 抽象接口、綁定和服務端點可以通過 WSDL 得到。如果您仔細查看上面的客戶機 API 示例,您將會注意到唯一由用戶提供的信息是用于服務的 WSDL 文件位置和所需要的股票報價符號。很明顯接下來是用 WSFL API 在運行時裝入這個服務和進行該調用。

    WSIF 分發包包含了演示怎樣執行 WSDL 的任意一個操作的 DynamicInvoker。它以 WSDL 文件的 URI 和所需的操作參數作為命令行參數(在最初的實現中只接受簡單的類型,如字符串),并且直接使用 WSIF API 完成工作。其用來調用股票報價服務的示例如清單 4 所示;您可以在包含 WSIF 分發包的文檔中查找詳細信息。

    因為這類調用不會導致生成存根類,并且不需要單獨的編譯周期,所以它很方便。

    清單 4:使用 DynamicInvoker 訪問股票報價服務

    java?clients.DynamicInvoker?http://services.xmethods.net/soap/urn:
    ????xmethods-delayed-quotes.wsdl?getQuote?IBM
    Reading?WSDL?document?from?'http://services.xmethods.net/soap/urn:
    ????xmethods-delayed-quotes.wsdl'
    Preparing?WSIF?dynamic?invocation
    Executing?operation?getQuote
    Result:
    Result=108.8
    Done!

    使用存根的調用
    在應用程序需要更抽象的服務視圖和不希望處理 WSIF 客戶機 API 的情況下,無存根調用不適用。WSIF 提供一個端口編譯器,如果給定一個 WSDL,與所用到的復雜類型的 Java 等價物(以 JavaBean 的形式)一起,端口編譯器將為每一個端口類型生成一個客戶機存根。使用生成存根的應用程序可以利用抽象服務接口,并且這樣與協議和 WSIF 客戶機 API 分離。對于實際服務調用,這些存根使用缺省端口。通過由 WSIF 的端口類型編譯器生成的存根使用股票報價服務的示例如清單 5 所示。

    清單 5:使用生成存根的 WSIF 訪問股票報價服務。

    StockquotePT?service?=?new?StockquotePTStub(WSIFUtils.readWSDL(null,?wsdlLocation),?
    ????
    null,?null);
    float?quote?=?service.getQuote("IBM");
    System.err.println?(
    ">>?Received?quote:?"+quote);

    值得注意的是存根駐留在某些受管環境(如應用程序服務器)的情況,它們能夠被定制;例如,可以改變負責返回恰當端口的工廠來定制端口選擇算法,或者可以改變用于調用自身的實際端口。

    在這篇文章中,我略述了對 WSIF 的需要,分析其通過高級 API 進行獨立于綁定的服務訪問的主要特征以及生成可定制的存根(通過其抽象接口使用服務)的端口類型編譯器的可用性。直接通過 SOAP 客戶機 API 和使用 WSIF API 進行服務訪問之間的對比展示了 WSIF(由服務的 WSDL 描述驅動)怎樣將 Web 服務調用的全部問題從以綁定為中心的觀點轉移到更抽象的級別。這是 WSIF 的設計原則之一,使服務綁定能被看作是根據特殊協議進行調用所需的代碼片斷,可以在任何時候插入它們。

    在接下來的文章,我將分析 WSIF 的體系結構,看一看它怎樣允許新的或更新的綁定實現被插入,它怎樣使定制的類型系統用于 Web 服務以及怎樣使運行時環境使用定制的探索性方法在多端口之間進行選擇。

    參考資料

    • 請參加關于這篇文章的討論論壇
    • 請下載 alphaworks 上的 WSIF 分發包,并且試驗比較簡單的樣本。它將給您一個由 WSIF 支持的不同調用風格的第一手示例以及它優于特定協議客戶機 API 的優勢。
    • 重溫 WSDL 規范,看一看允許哪一種擴展;如果用來為訪問 Web 服務定義 SOAP 綁定,您也可以學習 WSDL 的擴展機制。
    • 重溫 SOAP 規范本身。
    • 如果以前您沒有對 Web 服務編過程,Web Services Toolkit 是很好的起點。
    • 請查看 WSDL4J,一個可擴展的 WSDL 分析框架,WSIF 在此基礎上進行構建。

    關于作者
    Nirmal K. Mukhi 是 IBM 的 T J Watson Research Lab 的副研究員,自 2000 年 11 月,他一直在從事各種 Web 服務技術的研究。他還對 AI、創造性寫作以及過時的計算機游戲感興趣。您可以通過
    nmukhi@us.ibm.com 與 Nirmal 聯系。




    轉載自:http://www.itepub.net/page/article/htmldata/2004_10/17/76/article_3575_1.html
    posted on 2006-05-15 17:20 hopeshared 閱讀(567) 評論(0)  編輯  收藏 所屬分類: Web Service
    主站蜘蛛池模板: 18禁止看的免费污网站| 亚洲免费无码在线| 全免费毛片在线播放| 狼色精品人妻在线视频免费| 手机看黄av免费网址| 亚洲人成日本在线观看| 成人无遮挡裸免费视频在线观看| 亚洲天堂福利视频| 日本免费人成在线网站| 亚洲人成免费网站| 成年女人毛片免费播放视频m| 亚洲一级特黄无码片| 国产成人无码精品久久久久免费| 中文字幕人成人乱码亚洲电影| v片免费在线观看| 国产成人精品日本亚洲| 亚洲免费视频网站| 亚洲91精品麻豆国产系列在线| 最近中文字幕无吗免费高清| 亚洲熟妇无码AV| 亚洲免费观看在线视频| 亚洲精品午夜国产va久久| 国产一级一片免费播放i| 两个人的视频www免费| 亚洲免费在线视频| 无码国产精品一区二区免费式直播 | 国产精品国产自线拍免费软件| 狠狠色伊人亚洲综合成人| 国产精品免费观看调教网| 亚洲国产精品综合福利专区| 黑人粗长大战亚洲女2021国产精品成人免费视频 | 欧洲黑大粗无码免费| 亚洲成AV人片在WWW| 国产亚洲老熟女视频| 99在线免费观看视频| 亚洲欧美综合精品成人导航| 亚洲AV无码乱码在线观看| 日本免费在线观看| 亚洲AV成人无码久久WWW| 亚洲中文字幕无码一区二区三区 | 亚洲黄网在线观看|