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; };
<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>
<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>
<complexType name="personalInfo> <element name="averages" type="xsd:float" maxOccurs="20"/> </complexType>
<complexType name="TypeName
"> <complexContent> <restriction base="SOAP-ENC:Array"> <attribute ref="SOAP-ENC:arrayType" wsdl:arrayType="ElementType<ArrayBounds>
"/> </restriction> </complexContent> </complexType>
<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生成數據文件中忽略。
一個元素可以有一個內置類型定義,內置類型被指明,通過複合類型元素或者簡單類型元素。一旦你說明了是否數據類型是複合或者簡單,你可以定義任何你需要的數據類型。內置類型定義建議不被使用,因爲他不支持重用。