日期:2012-10-05  浏览次数:20451 次

[pre]WebServices入门
——理论篇
瑞联科技(中国)有限公司 李春林[/pre]
本文档是用ctrl+c -> ctrl+v产生出来的入门级文档,主要是想说明什么是webservices,webservices的架构,以及几个相关的xml文档。由于小弟知识及技术非常有限,文中不妥之处请各位兄台指正,小弟在此谢过啦。
什么是webservices?
从表面上看:Webservices 就是一个应用程序,它向外界暴露出一个能够通过Web进行调用的API。这就是说,你能够用编程的方法通过Web来调用这个应用程序。我们把调用这个Webservices 的应用程序叫做客户。
更专业的描述如下:Webservices是描述一些操作(利用标准化的 XML 消息传递机制可以通过网络访问这些操作)的接口。Webservices是用标准的、规范的 XML 概念描述的,称为 Webservices的服务描述。这一描述囊括了与服务交互需要的全部细节,包括消息格式(详细描述操作)、传输协议和位置。该接口隐藏了实现服务的细节,允许独立于实现服务基于的硬件或软件平台和编写服务所用的编程语言使用服务。这允许并支持基于 Webservices的应用程序成为松散耦合、面向组件和跨技术实现。Webservices履行一项特定的任务或一组任务。Webservices可以单独或同其它 Webservices一起用于实现复杂的聚集或商业交易,以及企业集成(EAI)。
Webservices模型
Webservices体系结构基于三种角色(服务提供者、服务注册中心和服务请求者)之间的交互。交互涉及发布、查找和绑定操作。这些角色和操作一起作用于 Webservices构件:

Webservices软件模块及其描述。在典型(并非 非典^_^)情况下,服务提供者托管可通过网络访问的软件模块(Webservices的一个实现)。服务提供者定义 Web 服务的服务描述并把它发布到服务请求者或服务注册中心。服务请求者使用查找操作来从本地或服务注册中心检索服务描述,然后使用服务描述与服务提供者进行绑定并调用 Web 服务实现或同它交互。服务提供者和服务请求者角色是逻辑结构,因而服务可以表现两种特性。下图 图示了这些操作、提供这些操作的组件及它们之间的交互。

Webservices协议栈
要以一种可互操作的方式执行发布、发现和绑定这三个操作,必须有一个包含每一层标准的 Webservices协议栈。下图展示了一个概念性 Webservices协议栈。上面的几层建立在下面几层提供的功能之上。垂直的条表示在协议栈中每一层必须满足的需求。左面的文本表示协议栈的那一层所应用的标准技术。

下面对上面是概念性的协议栈中,的每一层做一个粗糙的说明:
第一层(Network):这一层的这些协议都是现在运用比较广泛的协议啦,现在HTTP运用的最多啦,好处是显而易见的,其他的我就不多说了吧。(主要我怕我说出来会错误百出,被大家嘲笑。 *_*)。
第二层(XML-Based Messaging)这一层中主要体现怎么去调用Webservices。现在运用比较广泛的主要有两种,一种是xml-rpc(XML-Remote Procedure Call), 另一种是SOAP(Simple Object Access Protocal)。相比之下SOAP比XML-RPC有一定的优势:SOAP在处理复杂数据(如数组等)要比XML-RPC更容易一些;XML-RPC没有标准化错误代码;下面我们着重看看SOAP:
什么是SOAP?
对SOAP的一种简单理解:
SOAP是一种XML Application,SOAP简单的理解,就是这样的一个开放协议SOAP=RPC+HTTP+XML:采用HTTP作为底层通讯协议;RPC作为一致性的调用途径,XML作为数据传送的格式,允许服务提供者和服务客户经过防火墙在INTERNET进行通讯交互。如下图:

对SOAP更深一步的理解:
SOAP简单对象访问协议是在分散或分布式的环境中交换信息的简单的协议,是一个基于XML的协议,它包括四个部分:SOAP封装(envelop),封装定义了一个描述消息中的内容是什么,是谁发送的,谁应当接受并处理它以及如何处理它们的框架,如下图;SOAP编码规则(encoding rules),用于表示应用程序需要使用的数据类型的实例,一般遵循XMLSchema(定义了一系列的简单数据类型)规范; SOAP RPC表示(RPC representation),表示远程过程调用和应答的协定;SOAP绑定(binding),使用底层协议交换信息。虽然这四个部分都作为SOAP的一部分,作为一个整体定义的,但他们在功能上是相交的、彼此独立的。特别的,信封和编码规则是被定义在不同的XML命名空间(namespace)中,这样使得定义更加简单。

图:SOAP封装(envelop)
下面让我们来看一个SOAP的例子:
[pre]POST /calendar-request HTTP/1.1
Host: www.todaytech.com.cn
Content-Type: text/plain; charset="utf-8"
Content-Length: 507
SOAPAction:””

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:searchPaynoteResponse
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns1="http://external.charge.gfmis.todaytech.com">
<searchPaynoteReturn href="#id0"/>
</ns1:searchPaynoteResponse>
<multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xsi:type="ns2:ExternalPaynoteVO"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns2="http://vo.charge.gfmis.todaytech.com">
<paynoteNO xsi:type="xsd:string">0300000003004</paynoteNO>
<startDate xsi:type="xsd:string" xsi:nil="true"/>
<disaID xsi:type="xsd:string" xsi:nil="true"/>
<annotation xsi:type="xsd:string" xsi:nil="true"/>
<chargeItemNO3 xsi:type="xsd:string" xsi:nil="true"/>
<amount xsi:type="xsd:double">0.0</amount>
<chargeItemNO2 xsi:type="xsd:string" xsi:nil="true"/>
<loginKey xsi:type="xsd:string">YCpTEwKEw</loginKey>
<chargeItemNO1 xsi:type="xsd:str