日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Web Service学习笔记

發布時間:2025/7/14 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Web Service学习笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Web Service概述

Web Service的定義
W3C組織對其的定義例如以下,它是一個軟件系統,為了支持跨網絡的機器間相互操作交互而設計。Web Service服務通常被定義為一組模塊化的API,它們可以通過網絡進行調用,來運行遠程系統的請求服務。

這里我們從一個程序猿的視角來觀察web service。在傳統的程序編碼中,存在這各種的函數方法調用。通常,我們知道一個程序模塊M中的方法A,向其發出調用請求,并傳入A方法須要的參數P,方法A運行完畢后,返回處理結果R。這樣的函數或方法調用通常發生在同一臺機器上的同一程序語言環境下。如今的我們須要一種可以在不同計算機間的不同語言編寫的應用程序系統中,通過網絡通訊實現函數和方法調用的能力,而Web service正是應這樣的需求而誕生的。

最普遍的一種說法就是,Web Service = SOAP + HTTP + WSDL。當中,SOAP Simple Object Access Protocol)協議是web service的主體,它通過HTTP或者SMTP等應用層協議進行通訊,自身使用XML文件來描寫敘述程序的函數方法和參數信息,從而完畢不同主機的異構系統間的計算服務處理。這里的WSDL(Web Services Description Language)web 服務描寫敘述語言也是一個XML文檔,它通過HTTP向公眾公布,公告client程序關于某個詳細的 Web service服務的URL信息、方法的命名,參數,返回值等。
以下,我們先來熟悉一下SOAP協議,看看它是怎樣描寫敘述程序中的函數方法、參數及結果對象的。

SOAP協議簡單介紹

什么是SOAP
SOAP 指簡單對象訪問協議,它是一種基于XML的消息通訊格式,用于網絡上,不同平臺,不同語言的應用程序間的通訊。可自己定義,易于擴展。一條 SOAP 消息就是一個普通的 XML 文檔,包括下列元素:
? Envelope 元素,標識XML 文檔一條 SOAP 消息
? Header 元素,包括頭部信息的XML標簽
? Body 元素,包括全部的調用和響應的主體信息的標簽
? Fault 元素,錯誤信息標簽。

以上的元素都在 SOAP的命名空間http://www.w3.org/2001/12/soap-envelope中聲明;
SOAP的語法規則
? SOAP 消息必須用 XML 來編碼
? SOAP 消息必須使用 SOAP Envelope 命名空間
? SOAP 消息必須使用 SOAP Encoding 命名空間
? SOAP 消息不能包括 DTD 引用
? SOAP 消息不能包括 XML 處理指令

SOAP 消息的基本結構
Java代碼
  • <??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> ??
  • ??... ??
  • ??... ??
  • </soap:Header> ??
  • <soap:Body> ??
  • ??... ??
  • ??... ??
  • ??<soap:Fault> ??
  • ????... ??
  • ????... ??
  • ??</soap:Fault> ??
  • </soap:Body> ??
  • </soap:Envelope>??
  • <? 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>...... </soap:Header> <soap:Body>......<soap:Fault>......</soap:Fault> </soap:Body> </soap:Envelope>

    SOAP Envelope 元素
    Envelope 元素是 SOAP 消息的根元素。它指明 XML 文檔是一個SOAP 消息。它的屬性 xmlns:soap的值必須是http://www.w3.org/2001/12/soap-envelope。
    ? encodingStyle 屬性,語法:soap:encodingStyle="URI"
    encodingStyle 屬性用于定義文檔中使用的數據類型。此屬性可出如今不論什么 SOAP 元素中,并會被應用到元素的內容及元素的全部子元素上。
    Java代碼
  • <??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"> ??
  • ??... ??
  • ??Message?information?goes?here ??
  • ??... ??
  • </soap:Envelope>??
  • <? 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">...Message information goes here... </soap:Envelope>

    SOAP Header 元素

    • actor 屬性,語法soap:actor="URI"

    通過沿著消息路徑經過不同的端點,SOAP 消息可從某個發送者傳播到某個接收者。并不是 SOAP 消息的全部部分均打算傳送到 SOAP 消息的終于端點,只是,還有一個方面,或許打算傳送給消息路徑上的一個或多個端點。SOAP 的 actor 屬性可被用于將 Header 元素尋址到一個特定的端點。

    • mustUnderstand 屬性 ,語法soap:mustUnderstand="0|1"

    SOAP 的 mustUnderstand 屬性可用于標識標題項對于要對其進行處理的接收者來說是強制的還是可選的。假如您向 Header 元素的某個子元素加入了 "mustUnderstand="1",則要求處理此頭部的接收者必須認可此元素。
    Java代碼
  • <??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>??
  • <? 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,也能夠是用戶的應用程序自己定義的元素。下面是一個用戶定義的請求:
    Java代碼
  • <??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:Body> ??
  • ???<m:GetPrice?xmlns:m="http://www.jsoso.net/prices"> ??
  • ??????<m:Item>Apples</m:Item> ??
  • ???</m:GetPrice> ??
  • </soap:Body> ??
  • </soap:Envelope>??
  • <? 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:Body><m:GetPrice xmlns:m="http://www.jsoso.net/prices"><m:Item>Apples</m:Item></m:GetPrice> </soap:Body> </soap:Envelope>
    上面的樣例請求蘋果的價格。請注意,上面的 m:GetPrice 和 Item 元素是應用程序專用的元素。它們并非 SOAP 標準的一部分。而相應的 SOAP 響應應該相似這樣:
    Java代碼
  • <?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:Body> ??
  • ???<m:GetPriceResponse?xmlns:m="http://www.jsoso.net/prices"> ??
  • ??????<m:Price>1.90</m:Price> ??
  • ???</m:GetPriceResponse> ??
  • </soap:Body> ??
  • </soap:Envelope>??
  • <?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:Body><m:GetPriceResponse xmlns:m="http://www.jsoso.net/prices"><m:Price>1.90</m:Price></m:GetPriceResponse> </soap:Body> </soap:Envelope>

    SOAP Fault 元素
    Fault 元素表示 SOAP的錯誤消息。它必須是 Body 元素的子元素,且在一條 SOAP 消息中,Fault 元素僅僅能出現一次。Fault 元素擁有下列子元素:

    經常使用的SOAP Fault Codes


    HTTP協議中的SOAP 實例
    以下的樣例中,一個 GetStockPrice 請求被發送到了server。此請求有一個 StockName 參數,而在響應中則會返回一個 Price 參數。此功能的命名空間被定義在此地址中: "http://www.jsoso.net/stock"
    • SOAP 請求:(注意HTTP的Head屬性)

    Java代碼
  • POST?/InStock?HTTP/1.1??
  • Host:?www.jsoso.net ??
  • Content-Type:?application/soap+xml;?charset=utf-8??
  • Content-Length:?XXX ??
  • ??
  • <??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:Body?xmlns:m="http://www.jsoso.net/stock"> ??
  • ????<m:GetStockPrice> ??
  • ??????<m:StockName>IBM</m:StockName> ??
  • ????</m:GetStockPrice> ??
  • ??</soap:Body>?? ??
  • </soap:Envelope>??
  • POST /InStock HTTP/1.1 Host: www.jsoso.net Content-Type: application/soap+xml; charset=utf-8 Content-Length: XXX<? 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:Body xmlns:m="http://www.jsoso.net/stock"><m:GetStockPrice><m:StockName>IBM</m:StockName></m:GetStockPrice></soap:Body> </soap:Envelope>

    • SOAP 響應:(注意HTTP的Head屬性)

    Java代碼
  • HTTP/1.1?200?OK ??
  • Content-Type:?application/soap+xml;?charset=utf-8??
  • Content-Length:?XXX ??
  • ??
  • <??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:Body?xmlns:m="http://www.jsoso.net/stock"> ??
  • ????<m:GetStockPriceResponse> ??
  • ??????<m:Price>34.5</m:Price> ??
  • ????</m:GetStockPriceResponse> ??
  • ??</soap:Body>?? ??
  • </soap:Envelope>??
  • HTTP/1.1 200 OK Content-Type: application/soap+xml; charset=utf-8 Content-Length: XXX<? 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:Body xmlns:m="http://www.jsoso.net/stock"><m:GetStockPriceResponse><m:Price>34.5</m:Price></m:GetStockPriceResponse></soap:Body> </soap:Envelope>

    HTTP協議中的SOAP RPC工作流程


    WSDL簡單介紹
    介紹過了SOAP,讓我們關注Web Service中另外一個重要的組成WSDL。
    WSDL的主要文檔元素

    WSDL文檔能夠分為兩部分。頂部分由抽象定義組成,而底部分則由詳細描寫敘述組成。抽象部分以獨立于平臺和語言的方式定義SOAP消息,它們并不包括不論什么隨機器或語言而變的元素。這就定義了一系列服務,截然不同的應用都能夠實現。詳細部分,如數據的序列化則歸入底部分,由于它包括詳細的定義。在上述的文檔元素中,<types>、<message>、<portType>屬于抽象定義層,<binding>、<service>屬于詳細定義層。全部的抽象能夠是單獨存在于別的文件里,也能夠從主文檔中導入。

    WSDL文檔的結構實例解析
    以下我們將通過一個實際的WSDL文檔樣例來詳細說明各標簽的作用及關系。
    Java代碼
  • <?xml?version="1.0"?encoding="UTF-8"?> ??
  • <definitions ??
  • ?xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"??
  • ?xmlns:tns="http://www.jsoso.com/wstest"??
  • ?xmlns:xsd="http://www.w3.org/2001/XMLSchema"??
  • ?xmlns="http://schemas.xmlsoap.org/wsdl/"??
  • ?targetNamespace="http://www.jsoso.com/wstest"??
  • ?name="Example"> ??
  • ??
  • <types> ??
  • ??<xsd:schema> ??
  • ??<xsd:import??
  • ???namespace="http://www.jsoso.com/wstest"??
  • ???schemaLocation="http://localhost:8080/hello?xsd=1"></xsd:import> ??
  • ??</xsd:schema> ??
  • </types> ??
  • ??
  • <message?name="toSayHello"> ??
  • ??<part?name="userName"?type="xsd:string"></part> ??
  • </message> ??
  • <message?name="toSayHelloResponse"> ??
  • ??<part?name="returnWord"?type="xsd:string"></part> ??
  • </message> ??
  • ??
  • <message?name="sayHello"> ??
  • ??<part?name="person"?type="tns:person"></part> ??
  • ??<part?name="arg1"?type="xsd:string"></part> ??
  • </message> ??
  • <message?name="sayHelloResponse"> ??
  • ??<part?name="personList"?type="tns:personArray"></part> ??
  • </message> ??
  • <message?name="HelloException"> ??
  • ??<part?name="fault"?element="tns:HelloException"></part> ??
  • </message> ??
  • ??
  • <portType?name="Example"> ??
  • ??<operation?name="toSayHello"?parameterOrder="userName"> ??
  • ????<input?message="tns:toSayHello"></input> ??
  • ????<output?message="tns:toSayHelloResponse"></output> ??
  • ??</operation> ??
  • ??<operation?name="sayHello"?parameterOrder="person?arg1"> ??
  • ????<input?message="tns:sayHello"></input> ??
  • ????<output?message="tns:sayHelloResponse"></output> ??
  • ????<fault?message="tns:HelloException"?name="HelloException"></fault> ??
  • ??</operation> ??
  • </portType> ??
  • ??
  • <binding?name="ExamplePortBinding"?type="tns:Example"> ??
  • ??<soap:binding ??
  • ????transport="http://schemas.xmlsoap.org/soap/http"? ??
  • ????style="rpc"></soap:binding> ??
  • ??<operation?name="toSayHello"> ??
  • ????<soap:operation?soapAction="sayHello"></soap:operation> ??
  • ????<input> ??
  • ??????<soap:body?use="literal"??
  • ????????namespace="http://www.jsoso.com/wstest"></soap:body> ??
  • ????</input> ??
  • ????<output> ??
  • ??????<soap:body?use="literal"??
  • ?????????namespace="http://www.jsoso.com/wstest"></soap:body> ??
  • ????</output> ??
  • ??</operation> ??
  • ??<operation?name="sayHello"> ??
  • ????<soap:operation?soapAction="sayHello"></soap:operation> ??
  • ????<input> ??
  • ??????<soap:body?use="literal"??
  • ????????namespace="http://www.jsoso.com/wstest"></soap:body> ??
  • ????</input> ??
  • ????<output> ??
  • ??????<soap:body?use="literal"??
  • ????????namespace="http://www.jsoso.com/wstest"></soap:body> ??
  • ????</output> ??
  • ????<fault?name="HelloException"> ??
  • ??????<soap:fault?name="HelloException"?use="literal"></soap:fault> ??
  • ????</fault> ??
  • ????</operation> ??
  • </binding> ??
  • ??
  • <service?name="Example"> ??
  • ??<port?name="ExamplePort"?binding="tns:ExamplePortBinding"> ??
  • ????<soap:address?location="http://localhost:8080/hello"></soap:address> ??
  • ??</port> ??
  • </service> ??
  • </definitions>??
  • <?xml version="1.0" encoding="UTF-8"?> <definitionsxmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"xmlns:tns="http://www.jsoso.com/wstest"xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns="http://schemas.xmlsoap.org/wsdl/"targetNamespace="http://www.jsoso.com/wstest"name="Example"><types><xsd:schema><xsd:importnamespace="http://www.jsoso.com/wstest"schemaLocation="http://localhost:8080/hello?xsd=1"></xsd:import></xsd:schema> </types><message name="toSayHello"><part name="userName" type="xsd:string"></part> </message> <message name="toSayHelloResponse"><part name="returnWord" type="xsd:string"></part> </message><message name="sayHello"><part name="person" type="tns:person"></part><part name="arg1" type="xsd:string"></part> </message> <message name="sayHelloResponse"><part name="personList" type="tns:personArray"></part> </message> <message name="HelloException"><part name="fault" element="tns:HelloException"></part> </message><portType name="Example"><operation name="toSayHello" parameterOrder="userName"><input message="tns:toSayHello"></input><output message="tns:toSayHelloResponse"></output></operation><operation name="sayHello" parameterOrder="person arg1"><input message="tns:sayHello"></input><output message="tns:sayHelloResponse"></output><fault message="tns:HelloException" name="HelloException"></fault></operation> </portType><binding name="ExamplePortBinding" type="tns:Example"><soap:bindingtransport="http://schemas.xmlsoap.org/soap/http" style="rpc"></soap:binding><operation name="toSayHello"><soap:operation soapAction="sayHello"></soap:operation><input><soap:body use="literal"namespace="http://www.jsoso.com/wstest"></soap:body></input><output><soap:body use="literal"namespace="http://www.jsoso.com/wstest"></soap:body></output></operation><operation name="sayHello"><soap:operation soapAction="sayHello"></soap:operation><input><soap:body use="literal"namespace="http://www.jsoso.com/wstest"></soap:body></input><output><soap:body use="literal"namespace="http://www.jsoso.com/wstest"></soap:body></output><fault name="HelloException"><soap:fault name="HelloException" use="literal"></soap:fault></fault></operation> </binding><service name="Example"><port name="ExamplePort" binding="tns:ExamplePortBinding"><soap:address location="http://localhost:8080/hello"></soap:address></port> </service> </definitions>
    因為上面的事例XML較長,我們將其逐段分解解說

    WSDL文檔的根元素:<definitions>
    Java代碼
  • <definitions ??
  • ?xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"??
  • ?xmlns:tns="http://www.jsoso.com/wstest"??
  • ?xmlns:xsd="http://www.w3.org/2001/XMLSchema"??
  • ?xmlns="http://schemas.xmlsoap.org/wsdl/"??
  • ?targetNamespace="http://www.jsoso.com/wstest"??
  • ?name="Example"> ??
  • …… ??
  • …… ??
  • </definitions>??
  • <definitionsxmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"xmlns:tns="http://www.jsoso.com/wstest"xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns="http://schemas.xmlsoap.org/wsdl/"targetNamespace="http://www.jsoso.com/wstest"name="Example"> …… …… </definitions>
    <definitions>定義了文檔中用到的各個xml元素的namespace縮寫,也界定了本文檔自己的targetNamespace="http://www.jsoso.com/wstest",這意味著其他的XML要引用當前XML中的元素時,要聲明這個namespace。注意xmlns:tns="http://www.jsoso.com/wstest"這個聲明,它標示了使用tns這個前綴指向自身的命名空間。

    引用 WSDL文檔數據類型定義元素:<types>
    Java代碼
  • <types> ??
  • ??<xsd:schema> ??
  • ??<xsd:import??
  • ???namespace="http://www.jsoso.com/wstest"??
  • ???schemaLocation="http://localhost:8080/hello?xsd=1"></xsd:import> ??
  • ??</xsd:schema> ??
  • </types>??
  • <types><xsd:schema><xsd:importnamespace="http://www.jsoso.com/wstest"schemaLocation="http://localhost:8080/hello?xsd=1"></xsd:import></xsd:schema> </types>
    <types>標簽定義了當前的WSDL文檔用到的數據類型。要說明的是,為了最大程度的平臺中立性,WSDL 使用 XML Schema 語法來定義數據類型。這些數據類型用來定義web service方法的參數和返回指。對于通用的原生數據類型如:integer , boolean , char , float等,在W3C的標準文檔http://www.w3.org/2001/XMLSchema中已經做了定義。這里我們要引入的schema定義schemaLocation="http://localhost:8080/hello?xsd=1"是我們自己定義的Java對象類型。

    WSDL文檔消息體定義元素:< message >
    Java代碼
  • <message?name="toSayHello"> ??
  • ??<part?name="userName"?type="xsd:string"></part> ??
  • </message> ??
  • <message?name="toSayHelloResponse"> ??
  • ??<part?name="returnWord"?type="xsd:string"></part> ??
  • </message> ??
  • ??
  • <message?name="sayHello"> ??
  • ??<part?name="person"?type="tns:person"></part> ??
  • ??<part?name="arg1"?type="xsd:string"></part> ??
  • </message> ??
  • <message?name="sayHelloResponse"> ??
  • ??<part?name="personList"?type="tns:personArray"></part> ??
  • </message> ??
  • <message?name="HelloException"> ??
  • ??<part?name="fault"?element="tns:HelloException"></part> ??
  • </message>??
  • <message name="toSayHello"><part name="userName" type="xsd:string"></part> </message> <message name="toSayHelloResponse"><part name="returnWord" type="xsd:string"></part> </message><message name="sayHello"><part name="person" type="tns:person"></part><part name="arg1" type="xsd:string"></part> </message> <message name="sayHelloResponse"><part name="personList" type="tns:personArray"></part> </message> <message name="HelloException"><part name="fault" element="tns:HelloException"></part> </message>
    <message>元素定義了web service函數的參數。<message>元素中的每一個<part>子元素都和某個參數相符。輸入參數在<message>元素中定義,與輸出參數相隔離,輸出參數有自己的<message>元素。兼作輸入、輸出的參數在輸入輸出的<message>元素中有它們相應的<part>元素。輸出<message>元素以"Response"結尾,對Java而言方法得返回值就相應一個輸出的<message>。每一個<part>元素都有名字和類型屬性,就像函數的參數有參數名和參數類型。

    在上面的文檔中有兩個輸入參數、兩個輸出參數和一個錯誤參數(相應Java中的Exception)。

    ? 輸入參數<message>的name屬性分別命名為toSayHello,sayHello。
    toSayHello相應輸入參數userName,參數類型為xsd:string,在Java語言中就是String;
    sayHello相應兩個輸入參數person和arg1,類型為tns:person和xsd:string。這里tns:person類型就是引用了< types >標簽中的類型定義。

    ? 輸出參數<message>的name屬性分別命名為toSayHelloResponse和sayHelloResponse。
    這個名稱和輸入參數的<message>標簽name屬性相應,在其后面加上Response尾綴。
    toSayHelloResponse相應的返回值是returnWord,參數類型為xsd:string;
    sayHelloResponse相應的返回值是personList,參數類型為tns:personArray(自己定義類型);

    ? 錯誤參數<message>的name屬性為HelloException。
    它的<part>子標簽element而不是type來定義類型。

    以上的message標簽的name屬性通常使用web service函數方法名作為參照,錯誤參數標簽則使用異常類名為參照。標簽中的參數名稱,即part子元素的name屬性是可自己定義的(下一章節具體說明)。message標簽的參數類型將引用types標簽的定義。

    WSDL文檔函數體定義元素:< portType >
    Java代碼
  • <portType?name="Example"> ??
  • ??<operation?name="toSayHello"?parameterOrder="userName"> ??
  • ????<input?message="tns:toSayHello"></input> ??
  • ????<output?message="tns:toSayHelloResponse"></output> ??
  • ??</operation> ??
  • ??<operation?name="sayHello"?parameterOrder="person?arg1"> ??
  • ????<input?message="tns:sayHello"></input> ??
  • ????<output?message="tns:sayHelloResponse"></output> ??
  • ????<fault?message="tns:HelloException"?name="HelloException"></fault> ??
  • ??</operation> ??
  • </portType>??
  • <portType name="Example"><operation name="toSayHello" parameterOrder="userName"><input message="tns:toSayHello"></input><output message="tns:toSayHelloResponse"></output></operation><operation name="sayHello" parameterOrder="person arg1"><input message="tns:sayHello"></input><output message="tns:sayHelloResponse"></output><fault message="tns:HelloException" name="HelloException"></fault></operation> </portType>
    <portType> 元素是最重要的 WSDL 元素。它可描寫敘述一個 web service、可被運行的操作,以及相關的消息。portType的name屬性相應Java中的一個服務類的類名。<portType> 元素使用其子元素< operation>描寫敘述一個web service的服務方法。

    在<operation>元素中,name屬性表示服務方法名,parameterOrder屬性表示方法的參數順序,使用空格符切割多個參數,如:“parameterOrder="person arg1”。<operation>元素的子標簽<input>表示輸入參數說明,它引用<message>標簽中的輸入參數。<output>表示輸出參數說明,它引用<message>標簽中的輸出參數。<fault>標簽在Java方法中的特別用來表示異常(其他語言有相應的錯誤處理機制),它引用<message>標簽中的錯誤參數。

    WSDL綁定實現定義元素:< binding >
    Java代碼
  • <binding?name="ExamplePortBinding"?type="tns:Example"> ??
  • ??<soap:binding ??
  • ????transport="http://schemas.xmlsoap.org/soap/http"? ??
  • ????style="rpc"></soap:binding> ??
  • ??<operation?name="toSayHello"> ??
  • ????<soap:operation?soapAction="sayHello"></soap:operation> ??
  • ????<input> ??
  • ??????<soap:body?use="literal"??
  • ????????namespace="http://www.jsoso.com/wstest"></soap:body> ??
  • ????</input> ??
  • ????<output> ??
  • ??????<soap:body?use="literal"??
  • ?????????namespace="http://www.jsoso.com/wstest"></soap:body> ??
  • ????</output> ??
  • ??</operation> ??
  • ??<operation?name="sayHello"> ??
  • ????<soap:operation?soapAction="sayHello"></soap:operation> ??
  • ????<input> ??
  • ??????<soap:body?use="literal"??
  • ????????namespace="http://www.jsoso.com/wstest"></soap:body> ??
  • ????</input> ??
  • ????<output> ??
  • ??????<soap:body?use="literal"??
  • ????????namespace="http://www.jsoso.com/wstest"></soap:body> ??
  • ????</output> ??
  • ????<fault?name="HelloException"> ??
  • ??????<soap:fault?name="HelloException"?use="literal"></soap:fault> ??
  • ????</fault> ??
  • ????</operation> ??
  • </binding>??
  • <binding name="ExamplePortBinding" type="tns:Example"><soap:bindingtransport="http://schemas.xmlsoap.org/soap/http" style="rpc"></soap:binding><operation name="toSayHello"><soap:operation soapAction="sayHello"></soap:operation><input><soap:body use="literal"namespace="http://www.jsoso.com/wstest"></soap:body></input><output><soap:body use="literal"namespace="http://www.jsoso.com/wstest"></soap:body></output></operation><operation name="sayHello"><soap:operation soapAction="sayHello"></soap:operation><input><soap:body use="literal"namespace="http://www.jsoso.com/wstest"></soap:body></input><output><soap:body use="literal"namespace="http://www.jsoso.com/wstest"></soap:body></output><fault name="HelloException"><soap:fault name="HelloException" use="literal"></soap:fault></fault></operation> </binding>
    <binding>標簽是完整描寫敘述協議、序列化和編碼的地方,<types>,<message>和<portType>標簽處理抽象的數據內容,而<binding>標簽是處理傳輸數據的物理實現。
    <binding>標簽把前三部分的抽象定義詳細化。

    首先<binding>標簽使用<soap:binding>的transport和style屬性定義了Web Service的通訊協議HTTP和SOAP的請求風格RPC。其次<operation>子標簽將portType中定義的operation同SOAP的請求綁定,定義了操作名稱soapAction,輸出輸入參數和異常的編碼方式及命名空間。

    WSDL服務地址綁定元素:< service >
    Java代碼
  • <service?name="Example"> ??
  • ??<port?name="ExamplePort"?binding="tns:ExamplePortBinding"> ??
  • ????<soap:address?location="http://localhost:8080/hello"></soap:address> ??
  • ??</port> ??
  • </service>??
  • <service name="Example"><port name="ExamplePort" binding="tns:ExamplePortBinding"><soap:address location="http://localhost:8080/hello"></soap:address></port> </service>
    service是一套<port>元素。在一一相應形式下,每一個<port>元素都和一個location關聯。假設同一個<binding>有多個<port>元素與之關聯,能夠使用額外的URL地址作為替換。

    一個WSDL文檔中能夠有多個<service>元素,并且多個<service>元素十分實用,當中之中的一個就是能夠依據目標URL來組織端口。在一個WSDL文檔中,<service>的name屬性用來區分不同的service。在同一個service中,不同端口,使用端口的"name"屬性區分。

    這一章節,我們簡單的描寫敘述了WSDL對SOAP協議的支持,以及在Web Service中的作用。在接下來的章節中,我們將學習怎樣使用Java6.0的Annotation標簽來定義和生成相應的WSDL。

    JavaSE6.0下的Web Service
    從JavaSE6.0開始,Java引入了對Web Service的原生支持。我們僅僅須要簡單的使用Java的Annotation標簽就可以將標準的Java方法公布成Web Service。(PS:Java Annotation資料請參考JDK5.0 Annotation學習筆記(一) )

    但不是全部的Java類都能夠公布成Web Service。Java類若要成為一個實現了Web Service的bean,它須要遵循下邊這些原則:
    • ? 這個類必須是public類
    • ? 這些類不能是final的或者abstract
    • ? 這個類必須有一個公共的默認構造函數
    • ? 這個類絕對不能有finalize()方法

    以下我們將通過一個詳細的Java Web Service代碼樣例,配合上述的WSDL文件,講述怎樣編寫JavaSE6.0的原生Web Service應用。

    完整的Java Web Service類代碼

    Java代碼
  • package?org.jsoso.jws.server; ??
  • ??
  • import?java.util.ArrayList; ??
  • import?javax.jws.WebMethod; ??
  • import?javax.jws.WebParam; ??
  • import?javax.jws.WebResult; ??
  • import?javax.jws.WebService; ??
  • import?javax.jws.WebParam.Mode; ??
  • import?javax.jws.soap.SOAPBinding; ??
  • / ??
  • ?*?提供WebService服務的類 ??
  • ?*/ ??
  • @WebService(name="Example",?targetNamespace="http://www.jsoso.com/wstest",?serviceName="Example") ??
  • @SOAPBinding(style=SOAPBinding.Style.RPC) ??
  • public?class?Example?{ ??
  • ????private?ArrayList<Person>?persons?=?new?ArrayList<Person>();; ??
  • ????/** ?
  • ?????*? ?
  • ?????*?返回一個字符串 ?
  • ?????*?@param?userName ?
  • ?????*?@return ?
  • ?????*/??
  • ????@WebMethod(operationName="toSayHello",action="sayHello",exclude=false) ??
  • ????@WebResult(name="returnWord")//自己定義該方法返回值在WSDL中相關的描寫敘述 ??
  • ????public?String?sayHello(@WebParam(name="userName")String?userName)?{ ??
  • ????????return?"Hello:"?+?userName; ??
  • ????} ??
  • ??
  • ????/** ?
  • ?????*?web?services?方法的返回值與參數的類型不能為接口 ?
  • ?????*?@param?person ?
  • ?????*?@return ?
  • ?????*?@throws?HelloException ?
  • ?????*/??
  • ????@WebMethod(operationName="sayHello",?action="sayHello") ??
  • ????@WebResult(partName="personList") ??
  • ????public?Person[]?sayHello(@WebParam(partName="person",?mode=Mode.IN)Person?person,? ??
  • ????????????String?userName)?throws?HelloException?{ ??
  • ????????if?(person?==?null?||?person.getName()?==?null)?{ ??
  • ????????????throw?new?HelloException("說hello出錯,對像為空。。"); ??
  • ????????} ??
  • ????????System.out.println(person.getName()?+?"?對?"?+?userName?+?"?說:Hello,我今年"?+?person.getAge()?+?"歲"); ??
  • ????????persons.add(person); ??
  • ????????return?persons.toArray(new?Person[0]); ??
  • ????} ??
  • }??
  • package org.jsoso.jws.server;import java.util.ArrayList; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import javax.jws.WebParam.Mode; import javax.jws.soap.SOAPBinding; /* 提供WebService服務的類*/ @WebService(name="Example", targetNamespace="http://www.jsoso.com/wstest", serviceName="Example") @SOAPBinding(style=SOAPBinding.Style.RPC) public class Example {private ArrayList<Person> persons = new ArrayList<Person>();;/*** * 返回一個字符串* @param userName* @return*/@WebMethod(operationName="toSayHello",action="sayHello",exclude=false)@WebResult(name="returnWord")//自己定義該方法返回值在WSDL中相關的描寫敘述public String sayHello(@WebParam(name="userName")String userName) {return "Hello:" + userName;}/*** web services 方法的返回值與參數的類型不能為接口* @param person* @return* @throws HelloException*/@WebMethod(operationName="sayHello", action="sayHello")@WebResult(partName="personList")public Person[] sayHello(@WebParam(partName="person", mode=Mode.IN)Person person, String userName) throws HelloException {if (person == null || person.getName() == null) {throw new HelloException("說hello出錯,對像為空。。");}System.out.println(person.getName() + " 對 " + userName + " 說:Hello,我今年" + person.getAge() + "歲");persons.add(person);return persons.toArray(new Person[0]);} }

    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的消息協議,當中style屬性相應SOAP的文檔類型,可選的有RPC和DOCUMENT

    Annotation 3:@WebMethod(operationName="toSayHello",action="sayHello",exclude=false)
    @WebMethod定義Web Service運作的方法,
    屬性action 相應操作的活動 ,如<soap:operation soapAction="sayHello" />
    屬性operationName匹配的wsdl:operation 的名稱,如<operation name="toSayHello" parameterOrder="userName">
    屬性exclude 用于阻止將某一繼承方法公開為web服務,默覺得false

    Annotation 4:@WebResult(name="returnWord")
    @ WebResult定義方法返回值得名稱,如<part name="returnWord" type="xsd:string" />

    Annotation 5:@WebParam(partName="person", mode=Mode.IN
    @WebParam定義方法的參數名稱,如<part name="person" type="tns:person" />,當中mode屬性表示參數的流向,可選值有IN / OUT / INOUT

    這里要著重說明的是,上述Web Service類的sayHello方法中,帶有HelloException這個異常聲明,造成該服務類不能直接公布成Web Service。須要使用wsgen工具為其生存異常Bean。關于wsgen工具的使用,請參考wsgen與wsimport命令說明

    公布一個的Java Web Service
    在完畢了上述的Web Service Annotation凝視后,我們使用wsgen工具為其進行服務資源文件的構造(這里主要是生成一個名為org.jsoso.jws.server.jaxws.HelloExceptionBean的異常bean類),最后使用下面的類公布Web 服務:
    Java代碼
  • package?org.jsoso.jws.server; ??
  • ??
  • import?java.util.LinkedList; ??
  • import?java.util.List; ??
  • import?javax.xml.ws.Binding; ??
  • import?javax.xml.ws.Endpoint; ??
  • import?javax.xml.ws.handler.Handler; ??
  • ??
  • /** ?
  • ?*?@author?zsy?啟動web?services服務 ?
  • ?*/??
  • public?class?StartServer?{ ??
  • ??
  • ????/** ?
  • ?????*?@param?args ?
  • ?????*/??
  • ????public?static?void?main(String[]?args)?{ ??
  • ????????/* ?
  • ?????????*?生成Example?服務實例 ?
  • ?????????*/??
  • ????????Example?serverBean?=?new?Example(); ??
  • ????????/* ?
  • ?????????*?公布Web?Service到http://localhost:8080/hello地址 ?
  • ?????????*/??
  • ????????Endpoint?endpoint?=? ??
  • ???????????Endpoint.publish("http://localhost:8080/hello",?serverBean); ??
  • ????????Binding?binding?=?endpoint.getBinding(); ??
  • ????????/* ?
  • ?????????*?設置一個SOAP協議處理棧 ?
  • ?????????*?這里就簡單得打印SOAP的消息文本 ?
  • ?????????*/??
  • ????????List<Handler>?handlerChain?=?new?LinkedList<Handler>(); ??
  • ????????handlerChain.add(new?TraceHandler()); ??
  • ????????binding.setHandlerChain(handlerChain); ??
  • ????????System.out.println("服務已啟動?http://localhost:8080/hello"); ??
  • ????} ??
  • }??
  • package org.jsoso.jws.server;import java.util.LinkedList; import java.util.List; import javax.xml.ws.Binding; import javax.xml.ws.Endpoint; import javax.xml.ws.handler.Handler;/*** @author zsy 啟動web services服務*/ public class StartServer {/*** @param args*/public static void main(String[] args) {/** 生成Example 服務實例*/Example serverBean = new Example();/** 公布Web Service到http://localhost:8080/hello地址*/Endpoint endpoint = Endpoint.publish("http://localhost:8080/hello", serverBean);Binding binding = endpoint.getBinding();/** 設置一個SOAP協議處理棧* 這里就簡單得打印SOAP的消息文本*/List<Handler> handlerChain = new LinkedList<Handler>();handlerChain.add(new TraceHandler());binding.setHandlerChain(handlerChain);System.out.println("服務已啟動 http://localhost:8080/hello");} }
    在控制臺執行這個類,就能夠使用URL :http://localhost:8080/hello?wsdl 瀏覽到上文所描寫敘述的WSDL的全文了。這說明您的第一個Web Service應用公布成功!

    構建Web Serviceclient
    使用JavaSE6.0構建Web Service的client是一件相當簡單的事。這里我們要使用到JDK中的還有一個命令行工具wsimport。在控制臺下輸入下面命令:
    引用 wsimport -d ./bin -s ./src -p org.jsoso.jws.client.ref http://localhost:8080/hello?wsdl
    就可以在包org.jsoso.jws.client.ref中生成client的存根及框架文件。當中我們要使用的類僅僅有兩個:服務類Example_Service和本地接口Example。編寫例如以下client,就可以調用Web Service服務:
    Java代碼
  • package?org.jsoso.jws.client; ??
  • ??
  • import?org.jsoso.jws.client.ref.*; ??
  • ??
  • public?class?RunClient?{ ??
  • ??
  • ????/** ?
  • ?????*?@param?args ?
  • ?????*/??
  • ????public?static?void?main(String[]?args)?{ ??
  • ????????//初始化服務框架類 ??
  • ????????Example_Service?service?=?new?Example_Service(); ??
  • ????????//或者本地服務借口的實例 ??
  • ????????Example?server?=?(Example)?service.getExamplePort(); ??
  • ????????try?{ ??
  • ????????????//調用web?service的toSayHello方法 ??
  • ????????????System.out.println("輸入toSayHello的返回值——"?+?server.toSayHello("阿土"));????????? ??
  • ?????????????Person?person?=?new?Person(); ??
  • ?????????????person.setName("阿土"); ??
  • ?????????????person.setAge(25); ??
  • ?????????????//調用web?service的sayHello方法 ??
  • ?????????????server.sayHello(person,?"機器人"); ??
  • ????????????? ??
  • ?????????????person?=?new?Person(); ??
  • ?????????????person.setName("aten"); ??
  • ?????????????person.setAge(30); ??
  • ?????????????//調用web?service的sayHello方法 ??
  • ?????????????PersonArray?list?=?server.sayHello(person,?"機器人"); ??
  • ????????????//輸出返回值 ??
  • ?????????????System.out.println("/n下面輸入sayHello的返回值——"); ??
  • ????????????for?(Person?p?:?list.getItem())?{ ??
  • ????????????????System.out.println(p.getName()?+?":"?+?p.getAge()); ??
  • ????????????}??????????? ??
  • ????????}?catch?(HelloException_Exception?e)?{ ??
  • ????????????e.printStackTrace(); ??
  • ????????} ??
  • ????} ??
  • }??
  • package org.jsoso.jws.client;import org.jsoso.jws.client.ref.*;public class RunClient {/*** @param args*/public static void main(String[] args) {//初始化服務框架類Example_Service service = new Example_Service();//或者本地服務借口的實例Example server = (Example) service.getExamplePort();try {//調用web service的toSayHello方法System.out.println("輸入toSayHello的返回值——" + server.toSayHello("阿土")); Person person = new Person();person.setName("阿土");person.setAge(25);//調用web service的sayHello方法server.sayHello(person, "機器人");person = new Person();person.setName("aten");person.setAge(30);//調用web service的sayHello方法PersonArray list = server.sayHello(person, "機器人");//輸出返回值System.out.println("/n下面輸入sayHello的返回值——");for (Person p : list.getItem()) {System.out.println(p.getName() + ":" + p.getAge());} } catch (HelloException_Exception e) {e.printStackTrace();}} }
    屆此,本次Web Service的學習暫告一個段落。Java Web Service是一個相當龐大的知識體系,當中涉及的相關技術較多,這里無法一一道來,我們將會在今后的開發和使用中,同大家做進一步深入的探討和學習。

    附錄:wsgen與wsimport命令說明

    wsgen
    wsgen是在JDK的bin文件夾下的一個exe文件(Windows版),該命令的主要功能是用來生成合適的JAX-WS。它讀取Web Service的終端類文件,同一時候生成全部用于公布Web Service所依賴的源碼文件和經過編譯過的二進制類文件。這里要特別說明的是,通常在Web Service Bean中用到的異常類會另外生成一個描寫敘述Bean,假設Web Service Bean中的方法有申明拋出異常,這一步是必需的,否則server無法綁定該對像。此外,wsgen還能輔助生成WSDL和相關的xsd文件。wsgen從資源文件生成一個完整的操作列表并驗證web service是否合法,能夠完整公布。
    命令參數說明:
    • ? -cp 定義classpath
    • ? -r 生成 bean的wsdl文件的存放文件夾
    • ? -s 生成公布Web Service的源碼文件的存放文件夾(假設方法有拋出異常,則會生成該異常的描寫敘述類源文件)
    • ? -d 生成公布Web Service的編譯過的二進制類文件的存放文件夾(該異常的描寫敘述類的class文件)

    命令范例:wsgen -cp ./bin -r ./wsdl -s ./src -d ./bin -wsdl org.jsoso.jws.server.Example

    wsimport
    wsimport也是在JDK的bin文件夾下的一個exe文件(Windows版),主要功能是依據服務端公布的wsdl文件生成client存根及框架,負責與Web Service server通信,并在將其封裝成實例,client能夠直接使用,就像使用本地實例一樣。對Java而言,wsimport幫助程序猿生存調用web service所須要的client類文件.java和.class。要提醒指出的是,wsimport能夠用于非Java的server端,如:server端或許是C#編寫的web service,通過wsimport則生成Java的client實現。
    命令參數說明:
    • ? -d 生成client運行類的class文件的存放文件夾
    • ? -s 生成client運行類的源文件的存放文件夾
    • ? -p 定義生成類的包名

    命令范例:wsimport -d ./bin -s ./src -p org.jsoso.jws.client.ref http://localhost:8080/hello?wsdl??

    轉載于:https://www.cnblogs.com/blfshiye/p/4384446.html

    《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

    總結

    以上是生活随笔為你收集整理的Web Service学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。