Hello World
          Java技術(shù)學(xué)習(xí)
          posts - 17,  comments - 7,  trackbacks - 0

          Web Service描述語言 WSDL 詳解1
          Carlos C. Tapang
          Infotects

            為什么使用WSDL?

            像Internet協(xié)議之類的標(biāo)準(zhǔn)有沒有為權(quán)威所利用,或者人們這樣看待它是因?yàn)轫樦@的好處遠(yuǎn)遠(yuǎn)超出了代價?曾經(jīng)有許多試圖建立的標(biāo)準(zhǔn)都流產(chǎn)了。有時候,那些還沒有普遍使用的標(biāo)準(zhǔn)甚至由法令或政府規(guī)定強(qiáng)行推出:Ada語言就是一例。

            我相信正是跟隨標(biāo)準(zhǔn)所帶來的好處使它廣泛接受。例如,對于鐵路服務(wù)來說,真正重要的是,不同公司所鋪設(shè)的鐵路結(jié)合到一起,或者是來自好幾個公司的產(chǎn)品協(xié)調(diào)的工作在一起。幾家大的企業(yè)合力建立了SOAP標(biāo)準(zhǔn)。Web Service描述語言(WSDL)向這種Web Service的提供商和用戶推出了方便的協(xié)調(diào)工作的方法,使我們能更容易的獲得SOAP的種種好處。幾家公司的鐵道并在一起不算什么難事,他們所需遵循的只是兩軌間的標(biāo)準(zhǔn)距離。對Web Service來說,這要復(fù)雜得多。我們必須先制定出指定接口的標(biāo)準(zhǔn)格式。

            曾經(jīng)有人說SOAP并不真需要什么接口描述語言。如果SOAP是交流純內(nèi)容的標(biāo)準(zhǔn),那就需要一種語言來描述內(nèi)容。SOAP消息確實(shí)帶有某些類型信息,因此SOAP允許動態(tài)的決定類型。但不知道一個函數(shù)的函數(shù)名、參數(shù)的個數(shù)和各自類型,怎么可能去調(diào)用這個函數(shù)呢?沒有WSDL,我可以從必備文檔中確定調(diào)用語法,或者檢查消息。隨便何種方法,都必須有人參與,這個過程可能會有錯。而使用了WSDL,我就可以通過這種跨平臺和跨語言的方法使Web Service代理的產(chǎn)生自動化。就像COM和CORBA的IDL文件,WSDL文件由客戶和服務(wù)器約定。

            注意由于WSDL設(shè)計成可以綁定除SOAP以外的其他協(xié)議,這里我們主要關(guān)注WSDL在HTTP上和SOAP的關(guān)系。同樣,由于SOAP目前主要用來調(diào)用遠(yuǎn)程的過程和函數(shù),WSDL支持SOAP傳輸?shù)奈臋n規(guī)范。WSDL 1.1已經(jīng)作為記錄遞交給W3C(見http://www.w3.org/TR/wsdl.html

            WSDL文檔結(jié)構(gòu)

            若要理解XML文檔,將之看作塊狀圖表非常有用。下圖以XML的文檔形式說明了WSDL的結(jié)構(gòu),它揭示了WSDL文檔五個欄之間的關(guān)系。

            WSDL文檔可以分為兩部分。頂部分由抽象定義組成,而底部分則由具體描述組成。抽象部分以獨(dú)立于平臺和語言的方式定義SOAP消息,它們并不包含任何隨機(jī)器或語言而變的元素。這就定義了一系列服務(wù),截然不同的網(wǎng)站都可以實(shí)現(xiàn)。隨網(wǎng)站而異的東西如序列化便歸入底部分,因?yàn)樗唧w的定義。

            l 抽象定義

              Types

              獨(dú)立與機(jī)器和語言的類型定義

              Messages

              包括函數(shù)參數(shù)(輸入與輸出分開)或文檔描述

              PortTypes

              引用消息部分中消息定義來描述函數(shù)簽名(操作名、輸入?yún)?shù)、輸出參數(shù))

            2 具體定義

              Bindings

              PortTypes部分的每一操作在此綁定實(shí)現(xiàn)

              Services

              確定每一綁定的端口地址

            下面的圖中,箭頭連接符代表文檔不同欄之間的關(guān)系。點(diǎn)和箭頭代表了引用或使用關(guān)系。雙箭頭代表"修改"關(guān)系。3-D的箭頭代表了包含關(guān)系。這樣,各Messages欄使用Types欄的定義,PortTypes欄使用Messages欄的定義;Bindings欄引用了PortTypes欄,Services欄引用Bindings欄,PortTypes和Bindings欄包含了operation元素,而Services欄包含了port元素。PortTypes欄里的operation元素由Bindings欄里的operation元素進(jìn)一步修改或描述。
          jt-2001-10-12-image001.gif
          ???????????? 圖一:抽象定義和具體定義

            在此背景中,我將使用標(biāo)準(zhǔn)的XML術(shù)語來描述WSDL文檔。Element是指XML的元素,而"attribute"指元素的屬性。于是:

          < element? attribute ="attribute-value" > contents </ element >
          內(nèi)容也可能由一個或多個元素以遞歸的方式組成。根元素是所有元素之中最高級的元素。子元素總是從屬于另一個元素,父元素。

            注意,文檔之中可能只有一個Types欄,或根本沒有。所有其他的欄可以只有零元素、單元素或是多元素。WSDL的列表要求所有的欄以固定的順序出現(xiàn):import, types, message, portType, binding, service。所有的抽象可以是單獨(dú)存在于別的文件中,也可以從主文檔中導(dǎo)入。

          WSDL文件示例

            讓我們來研究一下WSDL文件,看看它的結(jié)構(gòu),以及如何工作。請注意這是一個非常簡單的WSDL文檔實(shí)例。我們的意圖只是說明它最顯著的特征。以下的內(nèi)容中包括更加詳細(xì)的討論。
          <?xml?version="1.0"?encoding="UTF-8"??>
          <definitions?name="FooSample"
           targetNamespace
          ="http://tempuri.org/wsdl/"
           xmlns:wsdlns
          ="http://tempuri.org/wsdl/"
           xmlns:typens
          ="http://tempuri.org/xsd"
           xmlns:xsd
          ="http://www.w3.org/2001/XMLSchema"
           xmlns:soap
          ="http://schemas.xmlsoap.org/wsdl/soap/"
           xmlns:stk
          ="http://schemas.microsoft.com/soap-toolkit/wsdl-extension"
           xmlns
          ="http://schemas.xmlsoap.org/wsdl/">

          <types>
          <schema?targetNamespace="http://tempuri.org/xsd"?
            xmlns
          ="http://www.w3.org/2001/XMLSchema"?
            xmlns:SOAP-ENC
          ="http://schemas.xmlsoap.org/soap/encoding/"?
            xmlns:wsdl
          ="http://schemas.xmlsoap.org/wsdl/"
            elementFormDefault
          ="qualified"?>
          </schema>
          </types>

          <message?name="Simple.foo">
           
          <part?name="arg"?type="xsd:int"/>
          </message>

          <message?name="Simple.fooResponse">
           
          <part?name="result"?type="xsd:int"/>
          </message>

          <portType?name="SimplePortType">
           
          <operation?name="foo"?parameterOrder="arg"?>
            
          <input?message="wsdlns:Simple.foo"/>
            
          <output?message="wsdlns:Simple.fooResponse"/>
           
          </operation>
          </portType>

          <binding?name="SimpleBinding"?type="wsdlns:SimplePortType">
           
          <stk:binding?preferredEncoding="UTF-8"?/>
           
          <soap:binding?style="rpc"?
            transport
          ="http://schemas.xmlsoap.org/soap/http"/>
           
          <operation?name="foo">
            
          <soap:operation?soapAction="http://tempuri.org/action/Simple.foo"/>
            
          <input>
             
          <soap:body?use="encoded"?namespace="http://tempuri.org/message/"?
              encodingStyle
          ="http://schemas.xmlsoap.org/soap/encoding/"?/>
            
          </input>
            
          <output>
             
          <soap:body?use="encoded"?namespace="http://tempuri.org/message/"?
              encodingStyle
          ="http://schemas.xmlsoap.org/soap/encoding/"?/>
            
          </output>
           
          </operation>
          </binding>

          <service?name="FOOSAMPLEService">
           
          <port?name="SimplePort"?binding="wsdlns:SimpleBinding">
            
          <soap:address?location="http://carlos:8080/FooSample/FooSample.asp"/>
           
          </port>
          </service>
          </definitions>

          以下是該實(shí)例文檔的總述:稍后我將詳細(xì)討論每一部分的細(xì)節(jié)。

            第一行申明該文檔是XML。盡管這并不是必需的,但它有助于XML解析器決定是否解析WSDL文件或只是報錯。第二行是WSDL文檔的根元素:<definitions>。一些屬性附屬于根元素,就像<schema>子元素對于<types>元素。

            <types>元素包含了Types欄。如果沒有需要聲明的數(shù)據(jù)類型,這欄可以缺省。在WSDL范例中,沒有應(yīng)用程序特定的types聲明,但我仍然使用了Types欄,只是為了聲明schema namespaces。

            <message>元素包含了Messages欄。如果我們把操作看作函數(shù),<message>元素定義了那個函數(shù)的參數(shù)。<message>元素中的每個<part>子元素都和某個參數(shù)相符。輸入?yún)?shù)在<message>元素中定義,與輸出參數(shù)相隔離--輸出參數(shù)有自己的<message>元素。兼作輸入、輸出的參數(shù)在輸入輸出的<message>元素中有它們相應(yīng)的<part>元素。輸出<message>元素以"Response"結(jié)尾,就像以前所用的"fooResponse"。每個<part>元素都有名字和類型屬性,就像函數(shù)的參數(shù)有參數(shù)名和參數(shù)類型。

            用于交換文檔時,WSDL允許使用<message>元素來描述交換的文檔。

            <part>元素的類型可以是XSD基類型,也可以是SOAP定義類型(soapenc)、WSDL定義類型(wsdl)或是Types欄定義的類型。

            一個PortTypes欄中,可以有零個、單個或多個<portType>元素。由于抽象PortType定義可以放置在分開的文件中,在某個WSDL文件中沒有<portType>元素是可能的。上面的例子里只是用了一個<portType>元素。而一個<portType>元素可在<operation>元素中定義一個或是多個操作。示例僅使用了一個名為"foo"的<operation>元素。這和某個函數(shù)名相同。<operation>元素可以有一個、兩個、三個子元素:<input>, <output> 和<fault>元素。每個<input>和<output>元素中的消息都引用Message欄中的相關(guān)的<message>元素。這樣,示例中的整個<portType>元素就和以下的C函數(shù)等效:

          int?foo(int?arg);

          這個例子足見XML和C相比要冗長的多。(包括<message>元素,XML在示例中共使用了12行代碼來表達(dá)相同的單行函數(shù)聲明。)

            Bindings欄可以有零個、一個或者多個<binding>元素。它的意圖是制定每個<operation>通過網(wǎng)絡(luò)調(diào)用和回應(yīng)。Services欄同樣可以有零個、一個、多個<service>元素。它還包含了<port>元素,每個<port>元素引用一個Bindings欄里的<binding>元素。Bindings和Services欄都包含WSDL文檔。

          Namespace
          <definitions>和子節(jié)點(diǎn)<schema>都是namespace屬性:

          <definitions?name="FooSample"
           targetNamespace
          ="http://tempuri.org/wsdl/"
           xmlns:wsdlns
          ="http://tempuri.org/wsdl/"
           xmlns:typens
          ="http://tempuri.org/xsd"
           xmlns:xsd
          ="http://www.w3.org/2001/XMLSchema"
           xmlns:soap
          ="http://schemas.xmlsoap.org/wsdl/soap/"
           xmlns:stk
          ="http://schemas.microsoft.com/soap-toolkit/wsdl-extension"
           xmlns
          ="http://schemas.xmlsoap.org/wsdl/">

          <types>
           
          <schema?targetNamespace="http://tempuri.org/xsd"?
            xmlns
          ="http://www.w3.org/2001/XMLSchema"?
            xmlns:SOAP-ENC
          ="http://schemas.xmlsoap.org/soap/encoding/"?
            xmlns:wsdl
          ="http://schemas.xmlsoap.org/wsdl/"
            elementFormDefault
          ="qualified"?>
           
          </schema>
          </types>?


            每個namespace屬性都聲明了一個縮略語,用在文檔中。例如"xmlns:xsd"就為 http://www.w3.org/2001/XMLSchema定義了一個縮略語(xsd)。這就允許對該namespace的引用只需簡單的在名字前加上前綴就可以了,如:"xsd:int"中的"xsd"就是合法的類型名。普通范圍規(guī)則可運(yùn)用于縮略前綴。也就是說,前綴所定義的元素只在元素中有效。

            Namespace派什么用?namespace的作用是要避免命名沖突。如果我建立一項(xiàng)Web Service,其中的WSDL文件包含一個名為"foo"的元素,而你想要使用我的服務(wù)與另一項(xiàng)服務(wù)連接作為補(bǔ)充,這樣的話另一項(xiàng)服務(wù)的WSDL文件就不能包含名為"foo"的元素。兩個服務(wù)器程序只有在它們在兩個事例中表示完全相同的東西時,才可以取相同的名字。如果有了表示區(qū)別的namespace,我的網(wǎng)絡(luò)服務(wù)里的"foo"就可以表示完全不同于另一個網(wǎng)絡(luò)服務(wù)里"foo"的含義。在你的客戶端里,你只要加以限制就可以引用我的"foo"。

            見下例:http://www.infotects.com/fooService#foo 就是完全限制的名字,相當(dāng)于"carlos:foo",如果我聲明了carlos作為http://www.infotects.com/fooService的快捷方式。請注意namespace中的URL是用來確定它們的唯一性的,同時也便于定位。URL所指向的地方不必是實(shí)際存在的網(wǎng)絡(luò)地址,也可以使用GUID來代替或補(bǔ)充URL。例如,GUID"335DB901-D44A-11D4-A96E-0080AD76435D"就是一個合法的namespace指派。

            targetNamespace屬性聲明了一個namespace,元素中所有的聲明的名字都列于其內(nèi)。在WSDL示例中,<definitions>的targetNamespace 是http://tempuri.org/wsdl。這意味著所有在WSDL文檔中聲明的名字都屬于這個namespace。<schema>元素有自己的targetNamespace屬性,其值為 http://tempuri.org/xsd ,在<schma>元素中定義的所有名字都屬于這個namespace而不是main的target namespace。

            <schema>元素的以下這行聲明了默認(rèn)的namespace。Schema中所有有效的名字都屬于這個namespace。

          xmlns="http://www.w3.org/2001/XMLSchema"

          posted on 2007-01-22 12:21 Java初心 閱讀(5218) 評論(0)  編輯  收藏 所屬分類: Web Service

          <2007年1月>
          31123456
          78910111213
          14151617181920
          21222324252627
          28293031123
          45678910

          常用鏈接

          留言簿(1)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 皮山县| 格尔木市| 舟山市| 富蕴县| 河池市| 电白县| 类乌齐县| 荥经县| 中西区| 金华市| 分宜县| 革吉县| 共和县| 遵化市| 车险| 华亭县| 东乌珠穆沁旗| 娄底市| 个旧市| 阳西县| 射洪县| 临安市| 泊头市| 永德县| 诸暨市| 丹凤县| 开封县| 泰和县| 马龙县| 嵊州市| 贵州省| 丰镇市| 光山县| 镶黄旗| 社旗县| 文昌市| 西城区| 宝坻区| 如东县| 赣州市| 禹州市|