Web Service概述
Web Service的定義
W3C組織對其的定義如下,它是一個軟件系統(tǒng),為了支持跨網(wǎng)絡(luò)的機器間相互操作交互而設(shè)計。Web Service服務(wù)通常被定義為一組模塊化的API,它們可以通過網(wǎng)絡(luò)進行調(diào)用,來執(zhí)行遠程系統(tǒng)的請求服務(wù)。
這里我們從一個程序員的視角來觀察web service。在傳統(tǒng)的程序編碼中,存在這各種的函數(shù)方法調(diào)用。通常,我們知道一個程序模塊M中的方法A,向其發(fā)出調(diào)用請求,并傳入A方法需要的參數(shù)P,方法A執(zhí)行完畢后,返回處理結(jié)果R。這種函數(shù)或方法調(diào)用通常發(fā)生在同一臺機器上的同一程序語言環(huán)境下。現(xiàn)在的我們需要一種能夠在不同計算機間的不同語言編寫的應(yīng)用程序系統(tǒng)中,通過網(wǎng)絡(luò)通訊實現(xiàn)函數(shù)和方法調(diào)用的能力,而Web service正是應(yīng)這種需求而誕生的。
最普遍的一種說法就是,Web Service = SOAP + HTTP + WSDL。其中,SOAP Simple Object Access Protocol)協(xié)議是web service的主體,它通過HTTP或者SMTP等應(yīng)用層協(xié)議進行通訊,自身使用XML文件來描述程序的函數(shù)方法和參數(shù)信息,從而完成不同主機的異構(gòu)系統(tǒng)間的計算服務(wù)處理。這里的WSDL(Web Services Description Language)web 服務(wù)描述語言也是一個XML文檔,它通過HTTP向公眾發(fā)布,公告客戶端程序關(guān)于某個具體的 Web service服務(wù)的URL信息、方法的命名,參數(shù),返回值等。
下面,我們先來熟悉一下SOAP協(xié)議,看看它是如何描述程序中的函數(shù)方法、參數(shù)及結(jié)果對象的。
SOAP協(xié)議簡介
什么是SOAP
SOAP 指簡單對象訪問協(xié)議,它是一種基于XML的消息通訊格式,用于網(wǎng)絡(luò)上,不同平臺,不同語言的應(yīng)用程序間的通訊。可自定義,易于擴展。一條 SOAP 消息就是一個普通的 XML 文檔,包含下列元素:
? Envelope 元素,標識XML 文檔一條 SOAP 消息
? Header 元素,包含頭部信息的XML標簽
? Body 元素,包含所有的調(diào)用和響應(yīng)的主體信息的標簽
? Fault 元素,錯誤信息標簽。
以上的元素都在 SOAP的命名空間http://www.w3.org/2001/12/soap-envelope中聲明;
SOAP的語法規(guī)則
? SOAP 消息必須用 XML 來編碼
? SOAP 消息必須使用 SOAP Envelope 命名空間
? SOAP 消息必須使用 SOAP Encoding 命名空間
? SOAP 消息不能包含 DTD 引用
? SOAP 消息不能包含 XML 處理指令
SOAP 消息的基本結(jié)構(gòu)
SOAP Envelope 元素
Envelope 元素是 SOAP 消息的根元素。它指明 XML 文檔是一個SOAP 消息。它的屬性 xmlns:soap的值必須是http://www.w3.org/2001/12/soap-envelope。
? encodingStyle 屬性,語法:soap:encodingStyle="URI"
encodingStyle 屬性用于定義文檔中使用的數(shù)據(jù)類型。此屬性可出現(xiàn)在任何 SOAP 元素中,并會被應(yīng)用到元素的內(nèi)容及元素的所有子元素上。
SOAP Header 元素
通過沿著消息路徑經(jīng)過不同的端點,SOAP 消息可從某個發(fā)送者傳播到某個接收者。并非 SOAP 消息的所有部分均打算傳送到 SOAP 消息的最終端點,不過,另一個方面,也許打算傳送給消息路徑上的一個或多個端點。SOAP 的 actor 屬性可被用于將 Header 元素尋址到一個特定的端點。
SOAP 的 mustUnderstand 屬性可用于標識標題項對于要對其進行處理的接收者來說是強制的還是可選的。假如您向 Header 元素的某個子元素添加了 "mustUnderstand="1",則要求處理此頭部的接收者必須認可此元素。
<??xml?version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Header>
<m:Trans
xmlns:m="http://www.jsoso.net/transaction/"?
soap:mustUnderstand="1"?
soap:actor="http://www.w3schools.com/appml/?“??>234</m:Trans>
</soap:Header>




</soap:Envelope>

SOAP Body 元素
必需的 SOAP Body 元素可包含打算傳送到消息最終端點的實際 SOAP 消息。Body元素中既可以包含SOAP定義的命名空間中的元素,如Fault,也可以是用戶的應(yīng)用程序自定義的元素。以下是一個用戶定義的請求:
上面的例子請求蘋果的價格。請注意,上面的 m:GetPrice 和 Item 元素是應(yīng)用程序?qū)S玫脑亍K鼈儾⒉皇?SOAP 標準的一部分。而對應(yīng)的 SOAP 響應(yīng)應(yīng)該類似這樣:
SOAP Fault 元素
Fault 元素表示 SOAP的錯誤消息。它必須是 Body 元素的子元素,且在一條 SOAP 消息中,F(xiàn)ault 元素只能出現(xiàn)一次。Fault 元素擁有下列子元素:

常用的SOAP Fault Codes

HTTP協(xié)議中的SOAP 實例
下面的例子中,一個 GetStockPrice 請求被發(fā)送到了服務(wù)器。此請求有一個 StockName 參數(shù),而在響應(yīng)中則會返回一個 Price 參數(shù)。此功能的命名空間被定義在此地址中: "http://www.jsoso.net/stock"
由于上面的事例XML較長,我們將其逐段分解講解
WSDL文檔的根元素:<definitions>
<message>元素定義了web service函數(shù)的參數(shù)。<message>元素中的每個<part>子元素都和某個參數(shù)相符。輸入?yún)?shù)在<message>元素中定義,與輸出參數(shù)相隔離,輸出參數(shù)有自己的<message>元素。兼作輸入、輸出的參數(shù)在輸入輸出的<message>元素中有它們相應(yīng)的<part>元素。輸出<message>元素以"Response"結(jié)尾,對Java而言方法得返回值就對應(yīng)一個輸出的<message>。每個<part>元素都有名字和類型屬性,就像函數(shù)的參數(shù)有參數(shù)名和參數(shù)類型。
在上面的文檔中有兩個輸入?yún)?shù)、兩個輸出參數(shù)和一個錯誤參數(shù)(對應(yīng)Java中的Exception)。
? 輸入?yún)?shù)<message>的name屬性分別命名為toSayHello,sayHello。
toSayHello對應(yīng)輸入?yún)?shù)userName,參數(shù)類型為xsd:string,在Java語言中就是String;
sayHello對應(yīng)兩個輸入?yún)?shù)person和arg1,類型為tns:person和xsd:string。這里tns:person類型就是引用了< types >標簽中的類型定義。
? 輸出參數(shù)<message>的name屬性分別命名為toSayHelloResponse和sayHelloResponse。
這個名稱和輸入?yún)?shù)的<message>標簽name屬性對應(yīng),在其后面加上Response尾綴。
toSayHelloResponse對應(yīng)的返回值是returnWord,參數(shù)類型為xsd:string;
sayHelloResponse對應(yīng)的返回值是personList,參數(shù)類型為tns:personArray(自定義類型);
? 錯誤參數(shù)<message>的name屬性為HelloException。
它的<part>子標簽element而不是type來定義類型。
??? 以上的message標簽的name屬性通常使用web service函數(shù)方法名作為參照,錯誤參數(shù)標簽則使用異常類名為參照。標簽中的參數(shù)名稱,即part子元素的name屬性是可自定義的(下一章節(jié)詳細說明)。message標簽的參數(shù)類型將引用types標簽的定義。
WSDL文檔函數(shù)體定義元素:< portType >
<portType> 元素是最重要的 WSDL 元素。它可描述一個 web service、可被執(zhí)行的操作,以及相關(guān)的消息。portType的name屬性對應(yīng)Java中的一個服務(wù)類的類名。<portType> 元素使用其子元素< operation>描述一個web service的服務(wù)方法。
在<operation>元素中,name屬性表示服務(wù)方法名,parameterOrder屬性表示方法的參數(shù)順序,使用空格符分割多個參數(shù),如:“parameterOrder="person arg1”。<operation>元素的子標簽<input>表示輸入?yún)?shù)說明,它引用<message>標簽中的輸入?yún)?shù)。<output>表示輸出參數(shù)說明,它引用<message>標簽中的輸出參數(shù)。<fault>標簽在Java方法中的特別用來表示異常(其它語言有對應(yīng)的錯誤處理機制),它引用<message>標簽中的錯誤參數(shù)。
WSDL綁定實現(xiàn)定義元素:< binding >
<binding>標簽是完整描述協(xié)議、序列化和編碼的地方,<types>,<message>和<portType>標簽處理抽象的數(shù)據(jù)內(nèi)容,而<binding>標簽是處理數(shù)據(jù)傳輸?shù)奈锢韺崿F(xiàn)。
<binding>標簽把前三部分的抽象定義具體化。
首先<binding>標簽使用<soap:binding>的transport和style屬性定義了Web Service的通訊協(xié)議HTTP和SOAP的請求風(fēng)格RPC。其次<operation>子標簽將portType中定義的operation同SOAP的請求綁定,定義了操作名稱soapAction,輸出輸入?yún)?shù)和異常的編碼方式及命名空間。
WSDL服務(wù)地址綁定元素:< service >
下面我們將通過一個具體的Java Web Service代碼例子,配合上述的WSDL文件,講述如何編寫JavaSE6.0的原生Web Service應(yīng)用。
完整的Java Web Service類代碼
Annotation 1@WebService(name="Example", targetNamespace="http://www.jsoso.com/wstest", serviceName="Example")
@WebService標簽主要將類暴露為WebService,其中targetNamespace屬性定義了自己的命名空間,serviceName則定義了< definitions >標簽和<service>標簽的name屬性。
Annotation 2:@SOAPBinding(style=SOAPBinding.Style.RPC)
@SOAPBinding標簽定義了WSDL文檔中SOAP的消息協(xié)議,其中style屬性對應(yīng)SOAP的文檔類型,可選的有RPC和DOCUMENT
Annotation 3:@WebMethod(operationName="toSayHello",action="sayHello",exclude=false)
@WebMethod定義Web Service運作的方法,
屬性action 對應(yīng)操作的活動 ,如<soap:operation soapAction="sayHello" />
屬性operationName匹配的wsdl:operation 的名稱,如<operation name="toSayHello" parameterOrder="userName">
屬性exclude 用于阻止將某一繼承方法公開為web服務(wù),默認為false
Annotation 4:@WebResult(name="returnWord")
@ WebResult定義方法返回值得名稱,如<part name="returnWord" type="xsd:string" />
Annotation 5:@WebParam(partName="person", mode=Mode.IN
@WebParam定義方法的參數(shù)名稱,如<part name="person" type="tns:person" />,其中mode屬性表示參數(shù)的流向,可選值有IN / OUT / INOUT
這里要著重說明的是,上述Web Service類的sayHello方法中,帶有HelloException這個異常聲明,造成該服務(wù)類不能直接發(fā)布成Web Service。需要使用wsgen工具為其生存異常Bean。關(guān)于wsgen工具的使用,請參考wsgen與wsimport命令說明
發(fā)布一個的Java Web Service
在完成了上述的Web Service Annotation注釋后,我們使用wsgen工具為其進行服務(wù)資源文件的構(gòu)造(這里主要是生成一個名為org.jsoso.jws.server.jaxws.HelloExceptionBean的異常bean類),最后使用以下的類發(fā)布Web 服務(wù):
在控制臺運行這個類,就可以使用URL :http://localhost:8080/hello?wsdl 瀏覽到上文所描述的WSDL的全文了。這說明您的第一個Web Service應(yīng)用發(fā)布成功!
構(gòu)建Web Service客戶端
使用JavaSE6.0構(gòu)建Web Service的客戶端是一件相當簡單的事。這里我們要使用到JDK中的另一個命令行工具wsimport。在控制臺下輸入以下命令:
即可在包org.jsoso.jws.client.ref中生成客戶端的存根及框架文件。其中我們要使用的類只有兩個:服務(wù)類Example_Service和本地接口Example。編寫如下客戶端,即可調(diào)用Web Service服務(wù):
附錄:wsgen與wsimport命令說明
wsgen
wsgen是在JDK的bin目錄下的一個exe文件(Windows版),該命令的主要功能是用來生成合適的JAX-WS。它讀取Web Service的終端類文件,同時生成所有用于發(fā)布Web Service所依賴的源代碼文件和經(jīng)過編譯過的二進制類文件。這里要特別說明的是,通常在Web Service Bean中用到的異常類會另外生成一個描述Bean,如果Web Service Bean中的方法有申明拋出異常,這一步是必需的,否則服務(wù)器無法綁定該對像。此外,wsgen還能輔助生成WSDL和相關(guān)的xsd文件。wsgen從資源文件生成一個完整的操作列表并驗證web service是否合法,可以完整發(fā)布。
命令參數(shù)說明:
命令范例:wsgen -cp ./bin -r ./wsdl -s ./src -d ./bin -wsdl org.jsoso.jws.server.Example
wsimport
wsimport也是在JDK的bin目錄下的一個exe文件(Windows版),主要功能是根據(jù)服務(wù)端發(fā)布的wsdl文件生成客戶端存根及框架,負責(zé)與Web Service 服務(wù)器通信,并在將其封裝成實例,客戶端可以直接使用,就像使用本地實例一樣。對Java而言,wsimport幫助程序員生存調(diào)用web service所需要的客戶端類文件.java和.class。要提醒指出的是,wsimport可以用于非Java的服務(wù)器端,如:服務(wù)器端也許是C#編寫的web service,通過wsimport則生成Java的客戶端實現(xiàn)。
命令參數(shù)說明:
命令范例:wsimport -d ./bin -s ./src -p org.jsoso.jws.client.ref http://localhost:8080/hello?wsdl
Web Service的定義
W3C組織對其的定義如下,它是一個軟件系統(tǒng),為了支持跨網(wǎng)絡(luò)的機器間相互操作交互而設(shè)計。Web Service服務(wù)通常被定義為一組模塊化的API,它們可以通過網(wǎng)絡(luò)進行調(diào)用,來執(zhí)行遠程系統(tǒng)的請求服務(wù)。
這里我們從一個程序員的視角來觀察web service。在傳統(tǒng)的程序編碼中,存在這各種的函數(shù)方法調(diào)用。通常,我們知道一個程序模塊M中的方法A,向其發(fā)出調(diào)用請求,并傳入A方法需要的參數(shù)P,方法A執(zhí)行完畢后,返回處理結(jié)果R。這種函數(shù)或方法調(diào)用通常發(fā)生在同一臺機器上的同一程序語言環(huán)境下。現(xiàn)在的我們需要一種能夠在不同計算機間的不同語言編寫的應(yīng)用程序系統(tǒng)中,通過網(wǎng)絡(luò)通訊實現(xiàn)函數(shù)和方法調(diào)用的能力,而Web service正是應(yīng)這種需求而誕生的。
最普遍的一種說法就是,Web Service = SOAP + HTTP + WSDL。其中,SOAP Simple Object Access Protocol)協(xié)議是web service的主體,它通過HTTP或者SMTP等應(yīng)用層協(xié)議進行通訊,自身使用XML文件來描述程序的函數(shù)方法和參數(shù)信息,從而完成不同主機的異構(gòu)系統(tǒng)間的計算服務(wù)處理。這里的WSDL(Web Services Description Language)web 服務(wù)描述語言也是一個XML文檔,它通過HTTP向公眾發(fā)布,公告客戶端程序關(guān)于某個具體的 Web service服務(wù)的URL信息、方法的命名,參數(shù),返回值等。
下面,我們先來熟悉一下SOAP協(xié)議,看看它是如何描述程序中的函數(shù)方法、參數(shù)及結(jié)果對象的。
SOAP協(xié)議簡介
什么是SOAP
SOAP 指簡單對象訪問協(xié)議,它是一種基于XML的消息通訊格式,用于網(wǎng)絡(luò)上,不同平臺,不同語言的應(yīng)用程序間的通訊。可自定義,易于擴展。一條 SOAP 消息就是一個普通的 XML 文檔,包含下列元素:
? Envelope 元素,標識XML 文檔一條 SOAP 消息
? Header 元素,包含頭部信息的XML標簽
? Body 元素,包含所有的調(diào)用和響應(yīng)的主體信息的標簽
? Fault 元素,錯誤信息標簽。
以上的元素都在 SOAP的命名空間http://www.w3.org/2001/12/soap-envelope中聲明;
SOAP的語法規(guī)則
? SOAP 消息必須用 XML 來編碼
? SOAP 消息必須使用 SOAP Envelope 命名空間
? SOAP 消息必須使用 SOAP Encoding 命名空間
? SOAP 消息不能包含 DTD 引用
? SOAP 消息不能包含 XML 處理指令
SOAP 消息的基本結(jié)構(gòu)
SOAP Envelope 元素
Envelope 元素是 SOAP 消息的根元素。它指明 XML 文檔是一個SOAP 消息。它的屬性 xmlns:soap的值必須是http://www.w3.org/2001/12/soap-envelope。
? encodingStyle 屬性,語法:soap:encodingStyle="URI"
encodingStyle 屬性用于定義文檔中使用的數(shù)據(jù)類型。此屬性可出現(xiàn)在任何 SOAP 元素中,并會被應(yīng)用到元素的內(nèi)容及元素的所有子元素上。
SOAP Header 元素
- actor 屬性,語法soap:actor="URI"
通過沿著消息路徑經(jīng)過不同的端點,SOAP 消息可從某個發(fā)送者傳播到某個接收者。并非 SOAP 消息的所有部分均打算傳送到 SOAP 消息的最終端點,不過,另一個方面,也許打算傳送給消息路徑上的一個或多個端點。SOAP 的 actor 屬性可被用于將 Header 元素尋址到一個特定的端點。
- mustUnderstand 屬性 ,語法soap:mustUnderstand="0|1"
SOAP 的 mustUnderstand 屬性可用于標識標題項對于要對其進行處理的接收者來說是強制的還是可選的。假如您向 Header 元素的某個子元素添加了 "mustUnderstand="1",則要求處理此頭部的接收者必須認可此元素。
















SOAP Body 元素
必需的 SOAP Body 元素可包含打算傳送到消息最終端點的實際 SOAP 消息。Body元素中既可以包含SOAP定義的命名空間中的元素,如Fault,也可以是用戶的應(yīng)用程序自定義的元素。以下是一個用戶定義的請求:
上面的例子請求蘋果的價格。請注意,上面的 m:GetPrice 和 Item 元素是應(yīng)用程序?qū)S玫脑亍K鼈儾⒉皇?SOAP 標準的一部分。而對應(yīng)的 SOAP 響應(yīng)應(yīng)該類似這樣:
SOAP Fault 元素
Fault 元素表示 SOAP的錯誤消息。它必須是 Body 元素的子元素,且在一條 SOAP 消息中,F(xiàn)ault 元素只能出現(xiàn)一次。Fault 元素擁有下列子元素:

常用的SOAP Fault Codes

HTTP協(xié)議中的SOAP 實例
下面的例子中,一個 GetStockPrice 請求被發(fā)送到了服務(wù)器。此請求有一個 StockName 參數(shù),而在響應(yīng)中則會返回一個 Price 參數(shù)。此功能的命名空間被定義在此地址中: "http://www.jsoso.net/stock"
- SOAP 請求:(注意HTTP的Head屬性)
- SOAP 響應(yīng):(注意HTTP的Head屬性)
由于上面的事例XML較長,我們將其逐段分解講解
WSDL文檔的根元素:<definitions>
引用
WSDL文檔數(shù)據(jù)類型定義元素:<types>
<message>元素定義了web service函數(shù)的參數(shù)。<message>元素中的每個<part>子元素都和某個參數(shù)相符。輸入?yún)?shù)在<message>元素中定義,與輸出參數(shù)相隔離,輸出參數(shù)有自己的<message>元素。兼作輸入、輸出的參數(shù)在輸入輸出的<message>元素中有它們相應(yīng)的<part>元素。輸出<message>元素以"Response"結(jié)尾,對Java而言方法得返回值就對應(yīng)一個輸出的<message>。每個<part>元素都有名字和類型屬性,就像函數(shù)的參數(shù)有參數(shù)名和參數(shù)類型。
在上面的文檔中有兩個輸入?yún)?shù)、兩個輸出參數(shù)和一個錯誤參數(shù)(對應(yīng)Java中的Exception)。
? 輸入?yún)?shù)<message>的name屬性分別命名為toSayHello,sayHello。
toSayHello對應(yīng)輸入?yún)?shù)userName,參數(shù)類型為xsd:string,在Java語言中就是String;
sayHello對應(yīng)兩個輸入?yún)?shù)person和arg1,類型為tns:person和xsd:string。這里tns:person類型就是引用了< types >標簽中的類型定義。
? 輸出參數(shù)<message>的name屬性分別命名為toSayHelloResponse和sayHelloResponse。
這個名稱和輸入?yún)?shù)的<message>標簽name屬性對應(yīng),在其后面加上Response尾綴。
toSayHelloResponse對應(yīng)的返回值是returnWord,參數(shù)類型為xsd:string;
sayHelloResponse對應(yīng)的返回值是personList,參數(shù)類型為tns:personArray(自定義類型);
? 錯誤參數(shù)<message>的name屬性為HelloException。
它的<part>子標簽element而不是type來定義類型。
??? 以上的message標簽的name屬性通常使用web service函數(shù)方法名作為參照,錯誤參數(shù)標簽則使用異常類名為參照。標簽中的參數(shù)名稱,即part子元素的name屬性是可自定義的(下一章節(jié)詳細說明)。message標簽的參數(shù)類型將引用types標簽的定義。
WSDL文檔函數(shù)體定義元素:< portType >
<portType> 元素是最重要的 WSDL 元素。它可描述一個 web service、可被執(zhí)行的操作,以及相關(guān)的消息。portType的name屬性對應(yīng)Java中的一個服務(wù)類的類名。<portType> 元素使用其子元素< operation>描述一個web service的服務(wù)方法。
在<operation>元素中,name屬性表示服務(wù)方法名,parameterOrder屬性表示方法的參數(shù)順序,使用空格符分割多個參數(shù),如:“parameterOrder="person arg1”。<operation>元素的子標簽<input>表示輸入?yún)?shù)說明,它引用<message>標簽中的輸入?yún)?shù)。<output>表示輸出參數(shù)說明,它引用<message>標簽中的輸出參數(shù)。<fault>標簽在Java方法中的特別用來表示異常(其它語言有對應(yīng)的錯誤處理機制),它引用<message>標簽中的錯誤參數(shù)。
WSDL綁定實現(xiàn)定義元素:< binding >
<binding>標簽是完整描述協(xié)議、序列化和編碼的地方,<types>,<message>和<portType>標簽處理抽象的數(shù)據(jù)內(nèi)容,而<binding>標簽是處理數(shù)據(jù)傳輸?shù)奈锢韺崿F(xiàn)。
<binding>標簽把前三部分的抽象定義具體化。
首先<binding>標簽使用<soap:binding>的transport和style屬性定義了Web Service的通訊協(xié)議HTTP和SOAP的請求風(fēng)格RPC。其次<operation>子標簽將portType中定義的operation同SOAP的請求綁定,定義了操作名稱soapAction,輸出輸入?yún)?shù)和異常的編碼方式及命名空間。
WSDL服務(wù)地址綁定元素:< service >
- ? 這個類必須是public類
- ? 這些類不能是final的或者abstract
- ? 這個類必須有一個公共的默認構(gòu)造函數(shù)
- ? 這個類絕對不能有finalize()方法
下面我們將通過一個具體的Java Web Service代碼例子,配合上述的WSDL文件,講述如何編寫JavaSE6.0的原生Web Service應(yīng)用。
完整的Java Web Service類代碼
Annotation 1@WebService(name="Example", targetNamespace="http://www.jsoso.com/wstest", serviceName="Example")
@WebService標簽主要將類暴露為WebService,其中targetNamespace屬性定義了自己的命名空間,serviceName則定義了< definitions >標簽和<service>標簽的name屬性。
Annotation 2:@SOAPBinding(style=SOAPBinding.Style.RPC)
@SOAPBinding標簽定義了WSDL文檔中SOAP的消息協(xié)議,其中style屬性對應(yīng)SOAP的文檔類型,可選的有RPC和DOCUMENT
Annotation 3:@WebMethod(operationName="toSayHello",action="sayHello",exclude=false)
@WebMethod定義Web Service運作的方法,
屬性action 對應(yīng)操作的活動 ,如<soap:operation soapAction="sayHello" />
屬性operationName匹配的wsdl:operation 的名稱,如<operation name="toSayHello" parameterOrder="userName">
屬性exclude 用于阻止將某一繼承方法公開為web服務(wù),默認為false
Annotation 4:@WebResult(name="returnWord")
@ WebResult定義方法返回值得名稱,如<part name="returnWord" type="xsd:string" />
Annotation 5:@WebParam(partName="person", mode=Mode.IN
@WebParam定義方法的參數(shù)名稱,如<part name="person" type="tns:person" />,其中mode屬性表示參數(shù)的流向,可選值有IN / OUT / INOUT
這里要著重說明的是,上述Web Service類的sayHello方法中,帶有HelloException這個異常聲明,造成該服務(wù)類不能直接發(fā)布成Web Service。需要使用wsgen工具為其生存異常Bean。關(guān)于wsgen工具的使用,請參考wsgen與wsimport命令說明
發(fā)布一個的Java Web Service
在完成了上述的Web Service Annotation注釋后,我們使用wsgen工具為其進行服務(wù)資源文件的構(gòu)造(這里主要是生成一個名為org.jsoso.jws.server.jaxws.HelloExceptionBean的異常bean類),最后使用以下的類發(fā)布Web 服務(wù):
在控制臺運行這個類,就可以使用URL :http://localhost:8080/hello?wsdl 瀏覽到上文所描述的WSDL的全文了。這說明您的第一個Web Service應(yīng)用發(fā)布成功!
構(gòu)建Web Service客戶端
使用JavaSE6.0構(gòu)建Web Service的客戶端是一件相當簡單的事。這里我們要使用到JDK中的另一個命令行工具wsimport。在控制臺下輸入以下命令:
引用
wsimport -d ./bin -s ./src -p org.jsoso.jws.client.ref? http://localhost:8080/hello?wsdl
即可在包org.jsoso.jws.client.ref中生成客戶端的存根及框架文件。其中我們要使用的類只有兩個:服務(wù)類Example_Service和本地接口Example。編寫如下客戶端,即可調(diào)用Web Service服務(wù):
屆此,本次Web Service的學(xué)習(xí)暫告一個段落。Java Web Service是一個相當龐大的知識體系,其中涉及的相關(guān)技術(shù)較多,這里無法一一道來,我們將會在今后的開發(fā)和使用中,同大家做進一步深入的探討和學(xué)習(xí)。
附錄:wsgen與wsimport命令說明
wsgen
wsgen是在JDK的bin目錄下的一個exe文件(Windows版),該命令的主要功能是用來生成合適的JAX-WS。它讀取Web Service的終端類文件,同時生成所有用于發(fā)布Web Service所依賴的源代碼文件和經(jīng)過編譯過的二進制類文件。這里要特別說明的是,通常在Web Service Bean中用到的異常類會另外生成一個描述Bean,如果Web Service Bean中的方法有申明拋出異常,這一步是必需的,否則服務(wù)器無法綁定該對像。此外,wsgen還能輔助生成WSDL和相關(guān)的xsd文件。wsgen從資源文件生成一個完整的操作列表并驗證web service是否合法,可以完整發(fā)布。
命令參數(shù)說明:
- ? -cp 定義classpath
- ? -r 生成 bean的wsdl文件的存放目錄
- ? -s 生成發(fā)布Web Service的源代碼文件的存放目錄(如果方法有拋出異常,則會生成該異常的描述類源文件)
- ? -d 生成發(fā)布Web Service的編譯過的二進制類文件的存放目錄(該異常的描述類的class文件)
命令范例:wsgen -cp ./bin -r ./wsdl -s ./src -d ./bin -wsdl org.jsoso.jws.server.Example
wsimport
wsimport也是在JDK的bin目錄下的一個exe文件(Windows版),主要功能是根據(jù)服務(wù)端發(fā)布的wsdl文件生成客戶端存根及框架,負責(zé)與Web Service 服務(wù)器通信,并在將其封裝成實例,客戶端可以直接使用,就像使用本地實例一樣。對Java而言,wsimport幫助程序員生存調(diào)用web service所需要的客戶端類文件.java和.class。要提醒指出的是,wsimport可以用于非Java的服務(wù)器端,如:服務(wù)器端也許是C#編寫的web service,通過wsimport則生成Java的客戶端實現(xiàn)。
命令參數(shù)說明:
- ? -d 生成客戶端執(zhí)行類的class文件的存放目錄
- ? -s 生成客戶端執(zhí)行類的源文件的存放目錄
- ? -p 定義生成類的包名
命令范例:wsimport -d ./bin -s ./src -p org.jsoso.jws.client.ref http://localhost:8080/hello?wsdl