Web Services 中XML、SOAP和WSDL的一些必要知識

Web Services 是由xml來定義數據格式的,經過SOAP協議在各個系統平臺中傳輸,那麼接下來討論下SOAP和WSDL的各自做用。web

SOAP和WSDL對Web Service、WCF進行深刻了解的基礎,所以花一些時間去了解一下是頗有必要的。chrome

1、SOAP(Simple Object Access Protocol)
若是咱們要調用遠程對象的方法,就一定要告訴對方,咱們要調用的是一個什麼方法,以及這個方法的參數的值等等。而後對方把數據返回給咱們。
這其中就涉及到兩個問題:一、數據如何在網絡上傳輸。二、如何表示數據?用什麼格式去表示函數以及它的參數等等。
一、SOAP的傳輸協議
SOAP的傳輸協議使用的就是HTTP協議。只不過HTTP傳輸的內容是HTML文本,而SOAP協議傳輸的是SOAP的數據。看一下下面的例子:
這是一個HTTP請求(請求google的首頁)的內容:
GET / HTTP/1.1 Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; CIBA) chromeframe/4.0
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Host: www.google.com
Cookie: PREF=ID=d8f9f1710bfa5f72:U=a5b3bec86b6433ef:NW=1:TM=1260238598:LM=1260241971:GM=1:S=q2agYsw3BsoOQMAs; NID=29=JgIGDDUx70IQTBVAnNEP_E9PLLKBI9STjzaBjgq1eWuDg-_jCgFpka59DrOC0aZKLbj4q77HU1VMKscXTP3OaseyTbv643c2XPe9dS7lsXDHAkAnS46vy-OU8XRqbmxJ; rememberme=true; SID=DQAAAH4AAABW7M4nVkTeOR7eJUmC1AJ4R6hYbmVewuy_uItLUTzZMUTpojdaHUExhPa_EPAkO9Ex1u3r7aPXZ5cj28xHnv2DbfRYf5AyaBcimciuOTITKSIkqn3QSpGDFkRS1Xn7EGzDpCV0V1xFlCu0erf_jfe_D6GOgC2P2S08jNdFS9Vpmw; HSID=AFEFTMA68EgNjkbil; __utmx=173272373.; __utmxx=173272373.

---------若是有Post的數據,這裏還會有Post的數據--------

這個是一個SOAP請求的內容:
POST /WebServices/WeatherWebService.asmx HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.3603)
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://WebXml.com.cn/getSupportCity"
Host: www.webxml.com.cn
Content-Length: 348
Expect: 100-continue
Connection: Keep-Alive

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><getSupportCity xmlns="http://WebXml.com.cn/"><byProvinceName>廣東</byProvinceName></getSupportCity></soap:Body></soap:Envelope>

能夠看到,一個SOAP請求其實就是一個HTTP請求,但爲了代表內容是SOAP的數據,須要加入上面請求中紅色字的部分來以示區別。也就是說,若是請求頭中有SOAPAction這一段,那麼請求會被看成SOAP的內容來處理而不會看成HTML來解析。能夠用上面指定SOAPAction頭來表示內容是SOAP的內容,也能夠指定 Content-Type: application/soap+xml 來表示內容是SOAP的內容。SOAP請求中最後的那段XML數據,這個就是請求的具體內容,這個就是SOAP規定的請求的數據格式,下面再詳細對格式進行說明

二、SOAP的數據格式
如今知道了SOAP是經過HTTP協議的POST方法來傳輸數據的,只不過是請求的Header中加了一些標誌來講明本身是一個SOAP請求。那麼數據的具體格式是怎麼規定的呢,咱們把上面請求的XML數據展開看一下:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<getSupportCity xmlns="http://WebXml.com.cn/">
<byProvinceName>廣東</byProvinceName>
</getSupportCity>
</soap:Body>
</soap:Envelope>
其中的<soap:Body>裏面的內容就是請求的內容,請求的方法爲getSupportCity,該方法有一個名爲byProvinceName的參數,參數的值爲「廣東」這個字符串。再看一下返回的內容:

HTTP/1.1 200 OK
Date: Mon, 14 Dec 2009 05:55:39 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Content-Length: 1052

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><getSupportCityResponse xmlns="http://WebXml.com.cn/"><getSupportCityResult><string>廣州 (59287)</string><string>深圳 (59493)</string><string>潮州 (59312)</string><string>韶關 (59082)</string><string>湛江 (59658)</string><string>惠州 (59298)</string><string>清遠 (59280)</string><string>東莞 (59289)</string><string>江門 (59473)</string><string>茂名 (59659)</string><string>肇慶 (59278)</string><string>汕尾 (59501)</string><string>河源 (59293)</string><string>揭陽 (59315)</string><string>梅州 (59117)</string><string>中山 (59485)</string><string>德慶 (59269)</string><string>陽江 (59663)</string><string>雲浮 (59471)</string><string>珠海 (59488)</string><string>汕頭 (59316)</string><string>佛山 (59279)</string></getSupportCityResult></getSupportCityResponse></soap:Body></soap:Envelope>
返回的HTTP頭中並無標誌來代表是一個SOAP的響應,由於的確沒有必要,請求方發送出的SOAP請求,返回的確定是SOAP的響應。

一個典型的SOAP請求格式的結構以下:
<?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.w3schools.com/transaction/"
soap:mustUnderstand="1">234
</m:Trans>
</soap:Header>

<soap:Body>
<m:GetPrice xmlns:m="http://www.w3schools.com/prices">
<m:Item>Apples</m:Item>
</m:GetPrice>
</soap:Body>

</soap:Envelope>

下面逐個解釋裏面的元素:
a) Envelope
SOAP的請求內容必須以Envelope作爲根節點。
xmlns:soap="http://www.w3.org/2001/12/soap-envelope",不能修改,不然會出錯。http://www.w3.org/2001/12/soap-envelope裏面有Envelope的schema的相關定義。有興趣的能夠去這個連接的內容。
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding",這個指定了數據元素的類型。

b) Header
這個是可選的,若是須要添加Header元素,那麼它必須是Envelope的第一個元素。
Header的內容並無嚴格的限制,咱們能夠本身添加一些和應用程序相關的內容,可是客戶端必定要記得處理這些Header元素,能夠加上mustUnderstand強制進行處理。

c) Body
這個就是請求的主題內容了,請求什麼函數,參數是什麼類型等等都在這裏面指定。 
用標籤表示一個函數,而後用子元素表示它的參數。

在調用中沒有指定參數和返回類型,這裏不須要指定,由於提供服務的一方本身已經規定好了數據類型,在調用時指定數據類型沒有任何意義。

2、WSDL(Web Services Description Language)
  WSDL是用來描述WebService的,它用XML的格式描述了WebService有哪些方法、參數類型、訪問路徑等等。咱們要使用一個WebService確定首先要獲取它的WSDL,在VS中添加一個Web 引用時,這些工做由開發環境幫咱們作了,開發環境根據WSDL文檔給Web Service生成了相應的代理類供咱們使用。
下面是一個HelloWorld的WebService的服務端代碼:
public class Service : System.Web.Services.WebService
{
public Service () {

//Uncomment the following line if using designed components 
//InitializeComponent(); 
}

[WebMethod]
public DateTime HelloWorld(int i)
{
return DateTime.Now;
}
}
  其對應的WebService的WSDL文檔以下:
1 <?xml version="1.0" encoding="utf-8"?>
2 <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://tempuri.org/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
3 <wsdl:types>
4 <s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
5 <s:element name="HelloWorld">
6 <s:complexType>
7 <s:sequence>
8 <s:element minOccurs="1" maxOccurs="1" name="i" type="s:int" />
9 </s:sequence>
10 </s:complexType>
11 </s:element>
12 <s:element name="HelloWorldResponse">
13 <s:complexType>
14 <s:sequence>
15 <s:element minOccurs="1" maxOccurs="1" name="HelloWorldResult" type="s:dateTime" />
16 </s:sequence>
17 </s:complexType>
18 </s:element>
19 </s:schema>
20 </wsdl:types>
21 <wsdl:message name="HelloWorldSoapIn">
22 <wsdl:part name="parameters" element="tns:HelloWorld" />
23 </wsdl:message>
24 <wsdl:message name="HelloWorldSoapOut">
25 <wsdl:part name="parameters" element="tns:HelloWorldResponse" />
26 </wsdl:message>
27 <wsdl:portType name="ServiceSoap">
28 <wsdl:operation name="HelloWorld">
29 <wsdl:input message="tns:HelloWorldSoapIn" />
30 <wsdl:output message="tns:HelloWorldSoapOut" />
31 </wsdl:operation>
32 </wsdl:portType>
33 <wsdl:binding name="ServiceSoap" type="tns:ServiceSoap">
34 <soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
35 <wsdl:operation name="HelloWorld">
36 <soap:operation soapAction="http://tempuri.org/HelloWorld" style="document" />
37 <wsdl:input>
38 <soap:body use="literal" />
39 </wsdl:input>
40 <wsdl:output>
41 <soap:body use="literal" />
42 </wsdl:output>
43 </wsdl:operation>
44 </wsdl:binding>
45 <wsdl:binding name="ServiceSoap12" type="tns:ServiceSoap">
46 <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
47 <wsdl:operation name="HelloWorld">
48 <soap12:operation soapAction="http://tempuri.org/HelloWorld" style="document" />
49 <wsdl:input>
50 <soap12:body use="literal" />
51 </wsdl:input>
52 <wsdl:output>
53 <soap12:body use="literal" />
54 </wsdl:output>
55 </wsdl:operation>
56 </wsdl:binding>
57 <wsdl:service name="Service">
58 <wsdl:port name="ServiceSoap" binding="tns:ServiceSoap">
59 <soap:address location="http://localhost:2206/WebSite1/Service.asmx" />
60 </wsdl:port>
61 <wsdl:port name="ServiceSoap12" binding="tns:ServiceSoap12">
62 <soap12:address location="http://localhost:2206/WebSite1/Service.asmx" />
63 </wsdl:port>
64 </wsdl:service>
65 </wsdl:definitions>

一個WSDL文檔由四部分組成:
一、types
  指定了WebService用到的全部數據類型,上面用到了兩種數據類型,int和datetime

二、message
  指明一個操做所用到的數據類型。
  HelloWorldSoapIn是指HelloWorld的輸入操做用到的數據類型,HelloWorldSoapOut是指HelloWorld的輸出操做用到的數據類型。兩者的element元素指出了與types中對應到的具體類型。

三、portType
  指出了這個WebService全部支持的操做,就是說有哪些方法可供調用。
  這裏支持一個HelloWorld調用,它的輸入和輸出對應到HelloWorldSoapIn和HelloWorldSoapOut這個兩個數據類型。

四、binding
  soap12:binding元素的transport指明傳輸協議,這裏是http協議。
  operation 指明要暴露給外界調用的操做。
  use屬性指定輸入輸出的編碼方式,這裏沒有指定編碼。

五、services
  指定服務的一些信息,主要是指定服務的訪問路徑。網絡

相關文章
相關標籤/搜索