SOAP(Simple Object Access Protocol,簡單對象訪問協議)作為一種信息交互協議在分布式應用中非常廣泛,如WebService。在使用.Net開發WebService時候,只需要在對應的方法上加上WebMethod特性然后就可以通過網絡進行SOAP消息的發送。這樣在平時使用Webservice時,可能不太關心SOAP消息的結構到底是怎樣的。下面大致說說SOAP消息的結構,以及使用工具監聽SOAP消息報文。
本節目錄:
- 1、XSD是什么
- 2、基於SOAP的數據交互系統是XSD的
- 3、SOAPSOAP消息結構
- 4、支持SOAP的協議
- 5、通過SOAPHeader擴展SOAP
- 6、SOAP自定義異常
- 7、監聽SOAP消息
1、XSD是什么
XSD(XML Scheme Definition,XML大綱定義)文檔用來描述XML的結構和內容。它本身也是一個XML文檔,通過它我們可以知道xml文檔中包含哪些節點,以及這些節點應該是什么類型的值等。常見的如WSDL文檔。
2、基於SOAP的數據交互系統應該是XSD的
WebService數據交互格式是基於SOAP的,而實際上SOAP就是具有SOAP格式的XML數據。基於XML的跨平台特性,各個系統在調用WebService時,都需要能准確的理解WebService需要什么類型的參數,有哪些參數,返回值是什么等等。要很好的說明這些問題,XSD是一種很好的選擇。所以說這類系統是XSD的。。
3、SOAP消息結構
首先看看如下SOAP請求消息:
它包含由SOAP信封(<soap:Envelope>) SOAP 頭(<soap:Header>) SOAP消息體 (<soap:Body>)組成。其中<soap:Envelope>是SOAP消息中的根節點,是SOAP消息中必須的部分;<soap:Header>是SOAP消息中可選部分,如果SOAP消息中含有它,那么它一定要是soap:Envelope>中的第一個元素節點;<soap:Body>是SOAP中必須部分,如果SOAP消息中沒有<soap:Header>,那么<soap:Body>必須是SOAP中第一個元素節點。
此外:在WebService返回給消費者時,如果服務發生異常,則返回給服務消費者還有<soap:Fault>元素節點,它包含在<soap:Body>中。如下:
<soap:Body> <soap:Fault> <faultcode xmlns:q0="ns=cnblogs.com/tyb1222">q0:code</faultcode> <faultstring>System.Web.Services.Protocols.SoapException: 0x00</faultstring> <faultactor/> <detail /> </soap:Fault> </soap:Body>
<faultcode>是<soap:Fault>中必須的元素節點,它讓消費者能識別錯誤。
<faultstring>是<soap:Fault>中必須的元素節點,用來描述錯誤文本信息
<faultactor/>不是<soap:Fault>中必須的元素節點,用來描述是在哪個路由節點上出錯。
<detail >用來描述與<soap:Body>有關的應用程序集錯誤信息。如果Body不能被正確處理,那 <detail >就是<soap:Fault>中必須元素
4、支持SOAP的協議
通常,訪問的WebService都是通過Web服務器。訪問Web服務器最常見的應用協議當然是久負盛名的HTTP了。HTTP也就成了支持SOAP最常用的協議。實際上支持SOAP支持的任何傳輸協議實現應用程序之間的通訊,包括TCP、SMTP等。
5、通過SOAPHeader擴展SOAP
在.Net平台上開發WebService,如果不通過SOAPHeader對SOAP頭進行擴展,SOAP消息中只有<soap:Envelope>、<soap:Body>這兩個SOAP中必須的兩個節點。很多時候SOAPHeader的使用也是SOAP種經常用到的部分,如通過SOAPHeader 對消費者做身份認證,或者給SOAP消息中使用Actor來進行SOAP消息路由等。
通過SOAPHeader擴展SOAP,可以在派生類中重寫SOAPHeader的實現。注意通過派生類實現對SOAPHeader重寫時,需要給派生類定義一個無參數構造函數,否則發布訪問WebService時會報因為沒有無參數構造函數而無法序列化的問題。
簡要介紹一下擴展SOAPHeader。
public class EaxmHeader : SoapHeader { public string UserName { get; set; } public string Password { get; set; } public EaxmHeader() { } public EaxmHeader(string userName,string password) { UserName = userName; Password = password; } }
然后在WebService具體函數接口上通過SOAPAttribute中MemberName設置為將EaxmHeader對象添加。如下:
[WebMethod]
[SoapHeader("header", Direction = SoapHeaderDirection.InOut)]
public int divide(int x, int y)
6、SOAP自定義異常
網絡通信中發射異常是難免的。有時為了保障服務的安全性而盡量少暴露服務信息並且需要讓消費者知曉在調用過程中發生異常的原因,一般可通過拋出自定義SOAPException異常,在<soap:Fault> 中自定義<faultcode>錯誤碼和 <faultstring>提示文本信息。如在catch中 throw new SOAPException(...)
7、監聽SOAP消息
SOAP消息監聽工具有MSSoapT(Microsoft SOAP ToolKit),tcpTrace等工具。下面就說說使用它們來監聽SOAP消息。
發布完WebService以后,可以通過WSDL通過WebService URI地址或者是WebService的WSDL文檔來生成服務代理類(參見前一節)。
代理類生產完成以后,在代理類的構造函數中設置端口號。如:
public class ExamService : SoapHttpClientProtocol { private SendOrPostCallback divideOperationCompleted; /// <remarks/> public ExamService() { Url = "http://193.168.11.94:8866/ExamService/WebService1.asmx"; } .... }
上面http://193.168.11.94:8866 就是在使用工具監聽SOAP消息時本地的端口號。注意:如果是在VS調試環境下,使用Asp.Net Development Server也會使用一個端口號,實際監聽的端口號是代理類中設置的端口,和它一般是不同。
7.1、使用MSSoapT監聽SOAP 消息
設置監聽端口、主機等信息,如下圖:
這樣,調試程序時,MSSoapT監聽到SOAP 消息如下圖:
上半部分為請求SOAP消息,下部分為返回SOAP消息。如下圖:
7.2、使用tcpTrace監聽SOAP 消息。
這樣監聽到的消息如下圖: