WSDL文檔使用web服務描述語言來定義服務。
文檔包括邏輯(抽象)部分和具體部分。
抽象部分用於定義獨立於實現的數據類型和消息,具體部分定義一個endpoint如何實現一個可以與外界進行交互的服務。
通常建議在寫代碼前定義WSDL文檔和XML schema,但是這就要求對WSDL非常熟悉。
邏輯部分:
包括types,message以及portType元素。types元素中,xml schema用來定義組成消息的數據的結構。一定數量的消息元素用來定義服務所用消息的格式。portType元素包括一個或多個operation元 素,用來定義被operation發送的消息。
具體部分:
包括binding和service元素。binding元素描述message元素描述的那些數據單元如何映射到一個具體的數據格式。Service元素包括一個或多個port元素,這些port元素用於定義endpoint。
總體上來說,一個WSDL文檔有以下元素組成:
- definitions--WSDL文檔的根元素,該元素的屬性指明了wsdl文檔的名稱,文檔的目標名字空間,以及WSDL文檔應用的名字空間的速記定義。
- types--數據單元的xml樣式定義,形成了服務所用消息的構建塊。
- portType---描述服務邏輯接口的operation元素的集合。
- operation--一個服務包含的操作的描述,當操作被調用時,操作被定義為兩個endpoint之間的消息傳遞。
- binding---一個endpoint的實際數據格式說明,一個binding元素定義如何將一個抽象消息映射到一個具體數據格式。該元素指明諸如參數順序,返回值等信息。
- service---相關port元素的集合,這些元素被庫藏,用戶組織endpoint定義。
- port--通過binding和物理地址定義的endpoint,這個元素將所有抽象定義聚集在一起。
設計一個WSDL的步驟:
1.定義服務用到的data types
2.定義服務用到的消息
3.定義服務接口
4.定義消息與接口之間的bindings和線上數據的具體呈現方式
5.定義每個服務的傳輸細節。
下面根據每步展開論述:
1.定義邏輯數據單元
定義一個服務時,第一件事情,你必須考慮的是作為暴露到外部的參數所用到的數據,將怎樣呈現。與那些是選用固定數據結構編碼的程序不同,服務必須定義出他們的數據以邏輯單元的形式,這包括兩步:
1.1將數據拆分成邏輯單元,這些單元能被映射為數據類型,並被服務的物理實現所引用。
如果你定義了一個服務接口,並且該接口已經實現,你必須將實現操作的數據類型轉換成xml元素,用於組裝成消息。如果你從頭開始,你必須定義你的消息構建時用到的構建塊,這樣的話,他們從實施角度看才有意義。
注1:定義服務數據單元可用的類型體系:根據WSDL規范,你可以使用任何類型體系。然而在W3C規范中定義的XML schema是首選的規范的類型體系。因此,XML架構是在Apache CXF的內在類型系統。
注2:xml schema:xml schema被用來定義一個xml文檔如何構建,用於定義一個文檔由哪些元素組成。這些元素可以使用xml schema類型,比如xsd:int的或者他可以使用用戶定義的類型,用戶定義類型也是使用xml元素的組合來構建的餓,或者他們是用嚴格的已存在類型 構建。通過結合類型定義和元素定義,你可以創建復雜的XML文檔可以包含復雜的數據。當定義服務使用的數據單元時,你可以定義他們作為類型,這些類型指明消息組成部分的結構,你也能夠定義你的消息單元作為組成消息結構的元素。
注3:生成數據單元的考慮:你可以考慮簡單地生成邏輯數據單元,這些單元直接映射你在服務中使用的數據類型。當以這個方式工作時,必須緊密遵循構建RPC 類型應用程序的構建模型,這不是構建面向服務架構程序必須的策略。webservice組織提供了一定數量的手冊來定義數據單元,另外W3C也提供了下 main的手冊來教你如何使用xml schema展現數據類型。
1.2將數據單元(data units)添加到文檔
依賴於你如何選擇去生成WSDL文檔,生成新的數據定義要求有大量的知識,CXF GUI工具提供一定數量的幫助來描述數據類型。其他的xml編輯器提供不同級別的幫助。不論你選擇哪種編輯器,擁有一些與文檔相關的知識是很重要的。
定義WSDL中用到的數據,需以下步驟:
a.確定接口要用到的所有數據單元
b.在文檔中生成一個types元素。
c.創建一個schema元素,作為types元素的子元素
d.complex類型是元素的集合,使用complexType元素來定義數據類型
e.對於每個數組來說,定義他的數據類型也使用complexType元素
f.對於每個復雜類型來說,都可以從簡單類型衍生出來,定義數據局類型可以通過simpleType元素。
g.對於每個枚舉類型,定義數據類型使用simpleType元素。
h.對於每個元素來說,定義他們使用element元素。
1.3 xml Schema simple types:
如果一個消息組件是簡單類型的話,那么就不需要給他定義一個類型。接口使用的復雜類型也是通過簡單類型定義的。
注1:輸入簡單類型:xml簡單類型是主要的放置元素,在element元素中。簡單類型也被使用在restriction元素和extension元素 的base屬性中。簡單類型總是使用xsd作為前綴,例如,為了指明類型int,你將輸入xsd:int在type屬性中。
<element name="simpleInt" type="xsd:int" />
CXF支持下列xml schema簡單類型:xsd:string,xsd:normalizedString,xsd:int,xsd:base64Binary等。
1.4定義復雜數據類型:
xml schema提供靈活和強大的機制來構建負責數據結構。你可以創建數據結構通過創建一個元素和屬性的序列。你看可以擴展已有類型來創建更復雜的類型。
另外,為了構建復雜數據結構,你可以描述特定的類型,諸如:枚舉類型。數據類型中的數據有一個特定的取值范圍,或者數據類型的數值必須遵循某種特定的模式,通過擴展或者限制原始類型。
1.5定義數據結構:
在xml schema中,數據單元是數據域的集合,這些數據域是通過負責類型元素定義的。指明一個復雜的類型需要三塊信息:
a.復雜元素的名稱需要被指定。
b.復雜類型的第一個子元素用來描述該結構的域的行為,當他被放入線上時。
c.每個結構中的域,都被用element元素定義。
下面的雷子是一個復雜類型有兩個子元素:
結構如下:
struct personalInfo { string name; int age; };
對應的WSDL文檔:
<complexType name="personalInfo"> <sequence> <element name="name" type="xsd:string" /> <element name="age" type="xsd:int" /> </sequence> </complexType>
注1:復雜類型的種類:
xml schema有三種方式描述當xml文檔被展現並通過線上展示時,其中的域如何被組織。第一個子元素確定哪種復雜類型被引用。下面展示了用來定義復雜類型行為的三種方式:
- sequence:所有的復雜類型域必須被顯示,並且他們必須有一個確定的次序,該次序與類型定義的次序相同。
- all:所有的復雜類型域都需要有,但是次序無所謂
- choice:僅僅是元素中一個可以出現在消息中。
注2:定義結構的部分:
你定義數據域,這些數據域是由一個結構體組成。每個復雜類型元素應該包括至少一個element元素。每個element元素對應已經定義的數據結構中的一個域。
為了充分描述數據結構中的域,element必須有兩個屬性:
name屬性:指明數據域的名稱並且是唯一的
type屬性:指明該域存儲的數據的類型。可以是簡單類型也可以是復雜類型。
除此而外還有兩個重要屬性:minOccurs和maxOccurs,這個屬性用來設置該域在結構中發生的次數上下限。缺省情況下每個字段值發生一次。使 用這些屬性,你可以改變結構體中一個域發生的次數。下面的例子中,previousJobs最少發生一次,最多7次。
<complexType name="personalInfo> <all> <element name="name" type="xsd:string"/> <element name="age" type="xsd:int"/> <element name="previousJobs" type="xsd:string: minOccurs="3" maxOccurs="7"/> </all> </complexType>
注3:定義屬性:在xml文檔中,屬性被包含在element內部的。例如在complexType元素中name就是屬性,它通常跟在<sequence>,<all>等元素的后面。例如:
<complexType name="personalInfo> <all> <element name="name" type="xsd:string"/> <element name="previousJobs" type="xsd:string" minOccurs="3" maxOccurs="7"/> </all> <attribute name="age" type="xsd:int" use="optional" /> </complexType>
1.6定義數組
CXF支持兩種方式來定義數組,第一種是定義一個復雜類型,采用簡單元素,他的最大發生屬性是個大於1的值,第二種方式是使用SOAP數組,SOAP數組提供增加的功能,比如ability來簡化定義多為數組並且發送分離后的數組。
復合類型數組:復合類型數組是特殊的sequence復合類型。你可以簡單定義一個復合類型通過簡單元素,並且制定該元素的最大發生maxOccurs屬性。例如,定義一個數組,擁有二個浮點數字,你可以使用復合類型如下:
<complexType name="personalInfo> <element name="averages" type="xsd:float" maxOccurs="20"/> </complexType>
你也可以定義一個最小發生屬性。
SOAP數組:SOAP數組定義通過SOAP-ENC:Array,該類型基於wsdl:arrayType元素。
<complexType name="TypeName"> <complexContent> <restriction base="SOAP-ENC:Array"> <attribute ref="SOAP-ENC:arrayType" wsdl:arrayType="ElementType<ArrayBounds>"/> </restriction> </complexContent> </complexType>
上述語法中,typename指定新定義的數組名,ElementType指定數組中元素的數據類型。ArrayBounds指定數組的維度及元素數量,單位數組通過[],多維通過[][]。
<complexType name="SOAPStrings"> <complexContent> <restriction base="SOAP-ENC:Array"> <attribute ref="SOAP-ENC:arrayType" wsdl:arrayType="xsd:string[]"/> </restriction> </complexContent> </complexType>
1.7通過extension定義類型
類似主要的編碼語言,xml schema允許你創建數據類型,這些數據類型集成已有的數據類型,這種機制被稱之為:extension。例如你可以創建一個新類型名叫alienInfo,它集成了PersonalInfo結構,通過鄭家了新的元素planet。
extension的類型定義包括四個部分:
a.通過name屬性來定義類型名
b.通過complexContent元素來指定新類型將擁有多余一個的元素。
c.被繼承的那個類,被稱之為base類型,通過base屬性來指定。
d.新類型和屬性被定義在extension元素中。例子如下:
<complexType name="alienInfo"> <complexContent> <extension base="personalInfo"> <sequence> <element name="planet" type="xsd:string"/> </sequence> </extension> </complexContent> </complexType>
1.8通過restriction來定義類型
簡單例子
<simpleType name="SSN"> <restriction base="xsd:string"> <pattern value="\d{3}-\d{2}-\d{4}"/> </restriction> </simpleType>
1.9定義枚舉類型:
<simpleType name="widgetSize"> <restriction base="xsd:string"> <enumeration value="big"/> <enumeration value="large"/> <enumeration value="mungo"/> </restriction> </simpleType>
2定義元素:
在xml schema中的元素體現為一個元素的實例。大多數最基本的元素有簡單元素組成。像element元素,他是由一定數量的復雜類型定義的。它有三個屬性:
- 名稱:一個需要的屬性來指明元素的名字
- type:指明元素的類型,這個類型可以是任何xml schema的原類型或者任何已經命名的復合類型。這個屬性屬性可以被省略,如果類型已經內置定義。
- nillable:指定是否元素可以從一個文檔中忽略,如果是ture,則元素可以被任何根據該SCHEMA生成數據文件中忽略。
一個元素可以有一個內置類型定義,內置類型被指明,通過復合類型元素或者簡單類型元素。一旦你說明了是否數據類型是復合或者簡單,你可以定義任何你需要的數據類型。內置類型定義建議不被使用,因為他不支持重用。