SOAP,即简单对象访问协议(Simple Object Access Protocol),是当今流行的技术之一,到底什么是SOAP呢?简单地说,SOAP可以通过网络实现对对象(而不是无组织无结构的文本信息、字节流)的访问和操作(SOAP仅仅定义了四种数据类型:String, Int, Float, NegetiveInteger,我想这也是Simple的由来之一吧)。为了更详细地了解SOAP,我翻译了下面的文章。
原文来自Sybex的Programming Spiders Bots and Aggregators in Java
XML作为存储数据的标准方法,关心的仅仅是数据的存储。然而,存储的数据必须加以利用——例如传输和接收。利用SOAP技术可以实现这种功能。我们可以把SOAP看作传送XML信息的邮局。虽然还存在很多其它的传输XML信息的方法,但SOPA在当前占主导地位。
SOAP是什么?SOAP是基于XML的,用于信息交互的轻量级协议,用于在分布(distributed)和分散(decentralized)的场合传输数据。分散,意味着运行于两台不同终端上的用户程序可以访问同一个SOAP服务提供者;分布,意味着多台机器可以提供相同的SOAP服务,平衡复杂以求得最佳性能。
SOAP主要由三部分组成:SOAP封(SOAP envelope),用于描述数据是什么以及如何处理;一组编码规则(Encoding rules),用于指定应用数据类型;以及一套调用约定(Call Convention),用于描述为远端应用程序提供的方法。
SOAP封 SOAP Envelope
SOAP封包含了SOAP消息的地址信息,作用类似于普通的信封。SOAP封包含了SOAP消息的目的服务器的地址,以及返回地址,以便让服务器发送相应。SOAP封由XML属性SOAP-ENV:Envelope规定。
编码规则 Encoding rules
每一条SOAP消息都包含了自身的编码规则。这些规则规定了SOAP协议的版本和SOAP信息表达不同组件的方法。编码规范由XML属性SOAP-ENV:encodingStyle规定。
调用约定 Call Convention
要执行Java程序,必须调用Java方法,SOAP也是一样。发送的SOAP消息的Call Convention部分规定了服务器应当执行的方法。该方法由XML标记SOAP_ENV:Body规定。
尽管实际应用中SOAP一般使用HTTP协议,但它并没有传输协议的限制,可以选择适合具体情况的协议加以实现。
SOAP如何传输数据从本质上来看,SOAP消息不过是从发送端到服务器端的单向传输——SOAP通过客户端向服务器发送请求。当然,有时服务器需要发送响应信息(Response)给客户端。但服务器的响应是非同步的(asynchronous),也许响应信息发送之前需要等待很长时间。这种请求-响应的模式就是SOAP通信。
尽管SOAP没有与任何网络协议绑定,但我们已经提到,SOAP消息通常都是通过HTTP协议发送的。因此,SOAP能够利用HTTP之类特定的网络系统的特性,获得最好的性能。例如,基于HTTP的SOAP可以利用同一个连接,以HTTP Response的方式发送SOAP响应,而其它协议并非都能实现双向连接。
SOAP消息也可以通过SMTP协议传送。在这种场合,SOAP消息实际上就是发送给用于处理请求的服务器的电子邮件。服务器返回的消息也都要通过邮件的方式传送给调用程序。在返回SOAP消息之间,可能需要等待很长的时间。
SOAP只是规定XML消息的结构,而不会影响用于交互的信息结构的具体操作。SOAP容许你像操作普通Java对象一样调用方法。但是,如何才能知道这些方法的名称呢?例如,检索当前温度的方法,到底是叫作GetCurrentTemprature,还是GetTemprature呢?显然,我们需要一套命名规范,也就是一个文件来定义web服务端(web service)提供的服务。Web服务定义语言(Web Service Definition Language)就是用来满足这种需求的。每个SOAP服务都应该提供一个规定与之通信的协议模版(protocol template)的WSDL文件。
SOAP的结构下面是一个基于HTTP的SOAP的例子。首先向CurrentTemperature服务传输一个GetCurrentTemprature的SOAP请求,该请求以一个String对象city code作为参数,代表需要检索温度的城市。接受该请求的SOAP服务器返回对应城市的温度,即一个浮点数。
POST /GetTemperature HTTP/1.1 Host: www.temperatureserver.com Content-Type: text/xml; charset="utf-8" Content-Length: nnnn SOAPAction: "Some-URI" <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Body> <m:GetCurrentTemperature xmlns:m="Some-URI"> <symbol>KSTL</symbol> </m: GetCurrentTemperature > </SOAP-ENV:Body> </SOAP-ENV:Envelope> 我们可以看到,SOAP Envelope元素SOAP-ENV:Envelope是该XML文件的顶层元素(Top Element)。该XML文件指定了XML namespace属性,确保SOAP标志符不会与其它XML标志符混淆。
SOAP-ENV:body部分包含了实际的方法调用。在本例中调用的方法为GetCurrentTemprature。返回地址,也就是SOAP响应的接收地址,在本例中为Some-URI,如果使用的HTTP协议,则应该设置为URL。如果使用SMTP协议,则应该设置为Email地址。方法的参数放在调用方法名之后,本例中只有一个参数,即symbol,指定城市的名称。
该消息被传送到服务器之后,服务器立即返回城市的温度作为响应。需要注意的是,该响应完全是非同步的,它并不是最初的POST的某一部分。
HTTP/1.1 200 OK Content-Type: text/xml; charset="utf-8" Content-Length: ### <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> <SOAP-ENV:Body> <m: GetCurrentTemperature xmlns:m="Some-URI"> <Temperature>34.5</GetCurrentTemperature> </m: GetCurrentTemperature> </SOAP-ENV:Body> </SOAP-ENV:Envelope> 看起来,返回的消息与请求非常相似。SOAP-ENV:body中包含的是返回的结果,方法名和请求中的一样,都是GetCurrentTemprature,之后跟着Temprature元素,包含对应城市的温度值。
从上面这个例子可以看到,发送SOAP消息必须提供一些信息:SOAP服务器的地址,调用方法的名称以及参数。最后还需要知道的是,从服务器返回的数据的类型。为此,SOAP提供了一套标准的方法描述这些信息,即WSDL。
WSDL
WSDL是描述网络服务的XML文件。当前web service操作的定义是很抽象的,然后与使用的网络协议以及信息格式相绑定,才能定义具体的服务提供者,即终点(endpoint)。有了WSDL,用户不再需要了解到底是哪个服务在处理他的请求,WSDL文件由处理请求的服务器生成,而不需要程序员指定具体的服务器。
在Web领域,传输协议和信息格式已经有了通行的标准。因此,SOAP也必须以结构化的方式指定通信操作。WSDL定义了一套XML语法,用于结构化地描述能够通过交互共享信息的终点的通信。WSDL文档并不仅仅提供了分布式系统的信息,也是自动实现应用程序交互细节的依据。
Trackback: http://tb.donews.net/TrackBack.aspx?PostId=504870