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

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

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

2 具體定義
        Bindings
       PortTypes部分的每一操作在此綁定實現(xiàn)

  Services
          確定每一綁定的端口地址



下面的圖中,箭頭連接符代表文檔不同欄之間的關(guā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元素進一步修改或描述。




首先看看一段簡單的JAVA代碼,我們用它作為WSDL的服務(wù)實現(xiàn)代碼:

public class Test{
  
public String echo(String u){
    
return "Hello " + u;
  }

}



看看它導(dǎo)出的文件:

 

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

    <?
xml version="1.0" encoding="UTF-8" ?> 
<wsdl:definitions targetNamespace="http://localhost/axis/Test2.jws"
                                      xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
                                      xmlns:xsd
="http://www.w3.org/2001/XMLSchema" 
                                      xmlns:soapenc
="http://schemas.xmlsoap.org/soap/encoding/" 
                                      xmlns:wsdlsoap
="http://schemas.xmlsoap.org/wsdl/soap/"
                                      xmlns:apachesoap="http://xml.apache.org/xml-soap" 
                                      xmlns:intf
="http://localhost/axis/Test2.jws" 
                                      xmlns:impl
="http://localhost/axis/Test2.jws">
<!-- 
WSDL created by Apache Axis version: 1.4
Built on Apr 22, 2006 (06:55:48 PDT)

  
--> 

定義好操作(或方法)以后,現(xiàn)在需要指定將向它們發(fā)送和從它們返回的參數(shù)。在 WSDL 術(shù)語中,所有參數(shù)稱為“消息”。認(rèn)為您是在遞送消息而結(jié)果得到返回的消息是有用的。方法調(diào)用是這樣一種操作:它準(zhǔn)備返回“消息”來響應(yīng)進入的消息。



<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 name="echoResponse">   //返回的消息
  
<wsdl:part name="echoReturn" type="xsd:string" /> 
  
</wsdl:message>
<wsdl:message name="echoRequest">  //請求的消息
  
<wsdl:part name="u" type="xsd:string" /> 
  
</wsdl:message>

<definitions> 元素包含一個或多個 <portType> 元素,實際上,每個元素都是您希望表示的一系列 operation 。或者,您也可以將單個 portType 元素看作是將各種方法組成類的一個邏輯分組。例如,如果您的供應(yīng)鏈管理解決方案需要在客戶和供應(yīng)商之間進行交互,您最可能做的是分別定義與他們交互的功能性;也就是說,您將為用戶和供應(yīng)商各定義一個 portType。應(yīng)該將每個 portType 稱為 服務(wù),因此整個 WSDL 文件將成為一個服務(wù)集合。

<wsdl:portType name="Test2">   //一個portType可以看成一個類
<wsdl:operation name="echo" parameterOrder="u">   //一個operation就是一個方法
  
<wsdl:input name="echoRequest" message="impl:echoRequest" />   //輸入消息
  
<wsdl:output name="echoResponse" message="impl:echoResponse" />  //返回消息
  
</wsdl:operation>
  
</wsdl:portTyp>

消息傳遞和傳輸:
我以一種抽象方式定義了操作和消息,而不考慮實現(xiàn)的細節(jié)。實際上,WSDL 的任務(wù)是定義或描述 Web 服務(wù),然后提供一個對外部框架的引用來定義 WSDL 用戶將如何實現(xiàn)這些服務(wù)。可以將這個框架當(dāng)作 WSDL 抽象定義和它們的實現(xiàn)之間的“綁定( binding )”。

當(dāng)前,最流行的綁定( binding )技術(shù)是使用簡單對象訪問協(xié)議(SOAP)。WSDL 將指定能夠訪問 Web 服務(wù)實際實現(xiàn)的 SOAP 服務(wù)器,并且從那時起 SOAP 的整個任務(wù)就是將用戶從 WSDL 文件帶到它的實現(xiàn)



WSDL 編寫的第三個步驟是描述將 SOAP 與 WSDL 文件綁定到一起的過程。您將把 <binding> 元素包括到 <definitions> 元素內(nèi)。這個 binding 元素應(yīng)該有 nametype 屬性。 name 將標(biāo)識這個綁定而 type 將標(biāo)識您希望與這個綁定相關(guān)聯(lián)的 portType(一組操作)。

     
<wsdl:binding name="Test2SoapBinding" type="impl:Test2">

  <wsdlsoap:binding/> 元素。該元素的用途是聲明將把 SOAP 作為綁定和傳輸服務(wù)使用

  <wsdlsoap:binding> 元素有兩個屬性:style 和 transport。style 是一個可選屬性,它描述該綁定內(nèi)操作的性質(zhì)。transport 屬性指定 HTTP 作為該綁定將使用的級別較低的傳輸服務(wù)。SOAP 客戶機將從 WSDL 文件中讀取 SOAP 結(jié)構(gòu)并與另一端的 SOAP 服務(wù)器協(xié)調(diào).
  <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" /> 

 WSDL <operation> 元素,分別表示具體的操作。每個 <operation> 元素提供各自操作的綁定細節(jié)。因此,我提供了另一個 extensibility 元素,即 <wsdlsoap:operation/> (仍然是一個空元素,與它發(fā)生的那個操作相關(guān))。該 <soap:operation/> 元素有一個 soapAction 屬性,SOAP 客戶機將使用該屬性創(chuàng)建 SOAP 請求。

    //下面將WSDL描述與具體實現(xiàn)進行綁定,這里采用SOAP方式

<wsdl:operation name="echo">
  
<wsdlsoap:operation soapAction="" /> 
<wsdl:input name="echoRequest">
  
<wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://DefaultNamespace" /> 
  
</wsdl:input>
<wsdl:output name="echoResponse">
  
<wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost/axis/Test2.jws" /> 
  
</wsdl:output>
  
</wsdl:operation>
  
</wsdl:binding>
//下面將發(fā)布的服務(wù)與前面的SOAP綁定進行關(guān)聯(lián)
<wsdl:service name="Test2Service">
<wsdl:port name="Test2" binding="impl:Test2SoapBinding">
  
<wsdlsoap:address location="http://localhost/axis/Test2.jws" /> 
  
</wsdl:port>
  
</wsdl:service>



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

  Namespace派什么用?namespace的作用是要避免命名沖突。如果我建立一項Web Service,其中的WSDL文件包含一個名為"foo"的元素,而你想要使用我的服務(wù)與另一項服務(wù)連接作為補充,這樣的話另一項服務(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所指向的地方不必是實際存在的網(wǎng)絡(luò)地址,也可以使用GUID來代替或補充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。