第2章 Web服务协议文档格式.docx
《第2章 Web服务协议文档格式.docx》由会员分享,可在线阅读,更多相关《第2章 Web服务协议文档格式.docx(12页珍藏版)》请在冰豆网上搜索。
//schemas.xmlsoap.org/soap/envelope/"
>
<
Header>
!
--Transaction-specificheaderdetails-->
/SOAP-ENV:
Body>
--Transaction-specificelements-->
Envelope>
所有的信息都包含在SOAP的Envelope元素中。
在整个元素中包含了一个Body元素和一个可选的Header元素,这些元素都位于一个具体的SOAP命名空间中。
SOAP规范中的所有特殊的元素(即Envelope,Header和Body)都位于命名空间http:
//schemas.xmlsoap.org/soap/envelope/中。
1.Envelope
所有的SOAP消息都被加载到了一个Envelope元素中。
对于所有被发送和接收的SOAP消息来说,Envelope元素总是最外层或者是最上层的元素。
在Envelope元素内部,总是有一个单独的Body元素。
另外,可能含有一个单独的Header元素,该元素是可选的但是如果有Header元素的话,那么它必须是封套中的第一个元素。
用户自定义的元素必须紧随Body元素之后。
2.Header
SOAP的Header元素被用来发送有关SOAP消息的元信息。
这个信息可以包含事务处理的信息、调用程序的身份,或者是范围之外的其他数据。
SOAP规范中允许一个mustUnderstand属性可以被包含在Header的任意元素中。
Web服务接受的SOAP消息必须能够处理标记为mustUnderstand属性的元素,否则它就一定不能处理这个SOAP请求。
如果服务器不能处理或识别这个被标记的元素,那么它将返回一个表示错误的故障消息。
SOAP的mustUnderstand属性可用于标识标题项对于要对其进行处理的接收者来说是强制的还是可选的。
假如您向Header元素的某个子元素添加了mustUnderstand="
1"
,则它可指示处理此头部的接收者必须认可此元素。
假如此接收者无法认可此元素,则在处理此头部时必须失效。
3.Body
在SOAP消息中总是会出现Body元素,Body元素中包含了消息的中心内容。
下面给出一个在特殊Web服务上进行一连串调用的示例。
我们将以一个假想的Web服务来介绍SOAP消息的3种不同格式。
该Web服务所完成的工作是,将两个数字相加,并返回相加的结果。
服务器上的方法如下:
intAddNumbers(intnNum1,intnNum2);
对Web服务的SOAP请求如下所示:
Bodyxmlns:
addNum="
Some-URI"
addNum:
AddNumbers>
nNum1>
5<
/nNum1>
nNum2>
10<
/nNum2>
/addNum:
在Body元素自身中,串行化对Web服务的请求。
对SOAP请求的响应,来自Web服务本身,如下所示:
AddNumbersResponse>
return>
15<
/return>
可见,Web服务做出了响应,从方法中返回了值。
该值被附在Body元素中,并且被命名空间的前缀所限定。
由方法名称连接“Response”构成了响应元素的名称。
如果该方法调用不成功的话,将接收一个来自Web服务的SOAP故障消息。
该故障消息是由Body元素中的一个单独的Fault元素组成的。
这个Fault元素本身可以包含4个子元素,如下所示:
faultcode>
----供识别故障的代码
faultstring>
----可供人阅读的有关故障的说明
faultactor>
----有关是谁引发故障的信息
detail>
----存留涉及Body元素的应用程序专用错误信息
如果我们给Web服务发送的两个数字超出了运算范围,那么将产生下面的SOAP故障消息:
Fault>
Server<
/faultcode>
ApplicationError<
/faultstring>
/faultactor>
detailxmlns:
Message>
Overflow-Parameterstoolarge
ErrorCode>
1234<
/detail>
可见,返回的消息是一个SOAP故障消息,该故障消息为客户机报告了一个错误。
无论Web服务内部的错误是如何产生的,故障机制都提供了为客户机发送错误情况的统一方法。
2.1.2数据类型和SOAP串行化
如何将数据串行化到SOAP消息?
对于方法的参数和从成功的方法调用中返回的数据来说,数据必须被串行化。
大多数串行化规则来自XMLSchema标准。
下面以具体的示例进行介绍。
假设有一个用于计算订单的利率的方法如下:
floatGetTax(stringName,intOrderNumber,floatTotalCost);
给Web服务发送的SOAP消息如下:
Envelope
xmlns:
xsi="
//www.w3.org/2001/XMLSchema-instance"
getTax="
getTax:
GetTax>
Namexsi:
type="
string"
Amanda<
/Name>
OrderNumberxsi:
integer"
111<
/OrderNumber>
TotalCostxsi:
float"
7.06<
/TotalCost>
/getTax:
//www.w3.org/2001/XMLSchema-instance是我们使用的一个新的命名空间。
该命名空间将数据类型限定在XMLSchema规范中。
该命名空间将每个参数都显示地类型化为一个具体的数据类型。
依据XMLSchema规范中的可用数据类型,xsi:
type属性可以显示地指定变量类型。
被编码到SOAP消息中的每个参数都有一个与之关联的特定数据类型。
当不包含xsi:
type属性时,默认的元素类型为字符串型。
XMLSchema规范列出了很多通用的数据类型,大多数程序设计语言都可以使用这些通用的数据类型。
下面是一些通用数据类型的列表:
string(字符串型),boolean(布尔型),float(浮点型),int(整形),dateTime(日期/时间型),binary(二进制型)。
假设有另一个示例。
voidSomeMethod(intnIntIn,floatfFloatIn,BooleanbBoolIn,stingstrIn);
格式化被串行化的SOAPBody元素格式如下:
xxx="
xxx:
SomeMethod>
nIntInxsi:
int"
1<
/nIntIn>
fFloatInxsi:
3.1415<
/fFloatIn>
bBoolInxsi:
boolean"
true<
/bBoolIn>
strInxsi:
HelloWorld<
/strIn>
/xxx:
注意,方法名称是如何成为Body元素中的一个限定元素的。
在Body元素内部,每个参数作为一个类型化的元素被列了出来。
另外SOAP使用了一种非常简单的格式来串行化复杂的数据对象。
对象的名称被用作最外层的元素,每个数据元素都包含在一个类型化的子元素中。
假设有如下的定义:
publicstructbook
{
publicstringAuthor;
publicstringTitle;
publicfloatPrice;
}
则Book对象将被串行化到SOAP信息中,如下所示:
Book>
Authorxsi:
WilliamShakespeare<
/Author>
Titlexsi:
Macbeth<
/Title>
Pricexsi:
19.95<
/Price>
/Book>
若现在要从远程的Web服务上调用如下的方法:
booleanBuyBook(BookaBook);
该示例中需要的SOAP消息应完成调用远程Web服务的任务,消息中应该含有串行化的对象,SOAP请求消息如下:
bookStore="
bookStore:
BuyBook>
/bookStore:
该示例中,Book对象被串行化到XML格式中。
数据成员被创建为根类元素的子元素。
服务器上的SOAP处理器将读取这个信息包,并使用所提供的数据重新创建Book对象,并调用BuyBook方法。
SOAP还支持对数组的串行化,假设我们需要下面的方法来调用一个Web服务:
voidSortArray(int[]nArray);
发送到该Web服务的SOAP消息如下:
SOAP-ENC="
//schemas.xmlsoap.org/soap/encoding/"
sort="
sort:
SortArray>
SOAP-ENC:
ArraySOAP-ENC:
arrayType="
xsi:
int[5]"
>
int>
3<
/SOAP-ENC:
4<
Array>
/sort:
SOAP通过将数组包装在SOAP-ENC:
Array元素中的方式来编码这些数组。
该元素必须包含一个SOAP-ENC:
arrayType属性,该属性指定了组成数组的数据类型以及数组中的元素的个数。
在SOAP消息中,SOAP规范给出了许多表示数据的规则和标准。
SOAP规范中还有很多关于串行化的规则,很多高级的串行化格式包括了多引用值,即在SOAP消息中,使用XPointer语法可以从多个地方引用某个单独的数据元素,这样就节省了SOAP消息的空间,因为,在同一个SOAP消息中的一个单独的值能够被多次使用。
大多数情况下,SOAP消息对于开发人员来说都是透明的,正像DCOM调用的格式一样透明。
SOAP是基本消息传递的基础结构,通过SOAP协议能够使Web服务在任意系统之间进行通信。
2.1.3HTTP协议之上的SOAP
大多数对Web服务的请求会通过一个HTTPPOST命令进行发送,而SOAP消息却位于HTTP载荷中。
通过HTTP发送SOAP信息包需要具备以下条件:
POST命令中的Content-type必须被声明为text/xml。
POST命令中必须包含一个附加的SOAPAction题头。
其值是一个URI,该URI描述了SOAP包正在请求的Web服务。
下面是一个向Web服务发送HTTP消息的示例。
POST/GetQuote.aspxHTTP/1.1
Host:
Content-Type:
text/xml;
charset="
utf-8"
Content-Length:
nnn
SOAPAction:
"
uri:
RandomNameServer#GetName"
name="
name:
GetRandomQuote/>
在本例中,HTTP包被发送给了假想的URL:
//
HTTP/1.1200OK
GetRandomQuoteResponse>
Ajoysharedisajoydoubled.<
/name:
可见,发送给客户机的HTTP响应信息包含了HTTP题头和整个的SOAP响应消息,HTTP返回的代码200-OK表示这是一个成功的Web服务调用。
如果在Web服务处理的过程中发生了错误,则500-InternalServerError将作为HTTP的响应代码被返回,包含在HTTP包中的SOAP消息是一个表示有错误产生的故障消息,Fault元素是必须的。
如果随机引用服务器返回一个故障消息的话,则返回的HTTP响应代码应如下所示。
HTTP/1.1500InternalServerError
ServerError<
message>
Nomorequotestoday<
/message>
2.2WSDL协议
SOAP是一个标准,该标准定义了应如何对发送到Web服务的消息进行格式化和编码。
但是,如何才能知道给服务器发送了什么消息呢?
如何判断一个特殊的Web服务究竟提供了哪些方法呢?
这些方法接收哪些参数呢?
WSDL指网络服务描述语言(WebServicesDescriptionLanguage)。
WSDL是一种使用XML编写的文档。
这种文档可描述某个Webservice。
它可规定服务的位置,以及此服务提供的操作(或方法)。
目前有很多原来创建WSDL文件的工具。
ASP.NET提供了为所要发布的Web服务动态生成WSDL文档的功能,方法是传递一个WSDL命令,如
2.2.1格式
所有的WSDL文档都必须包含在一个definitions元素中。
WSDL文档是由下面4个主要部分组成的一个XML文档。
definitions>
types>
definitionoftypes........<
/types>
definitionofamessage....<
portType>
definitionofaport.......<
/portType>
binding>
definitionofabinding....<
/binding>
/definitions>
元素定义Webservice使用的数据类型。
为了最大程度的平台中立性,WSDL使用XMLSchema语法来定义数据类型。
元素定义一个操作的数据元素。
每个消息均由一个或多个部件组成。
可以把这些部件比作传统编程语言中一个函数调用的参数。
元素是最重要的WSDL元素。
它可描述一个Webservice、可被执行的操作,以及相关的消息。
可以把<
元素比作传统编程语言中的一个函数库(或一个模块、或一个类)。
元素为每个端口定义消息格式和协议细节。
以下是某个WSDL文档简化的片断。
messagename="
getTermRequest"
partname="
term"
type="
xs:
/>
getTermRe