SOAP消息

  对于使用WSDL的客户机和服务机来说,研究WSDL文件的一种方法就是决定什么来接受所发送的信息。尽管SOAP使用底层协议,如IP和HTTP等,但应用程序决定了服务器与客户机之间交互的高级协议。也就是说,进行一项操作,比如"echoint"把输入的整数送回,参数的数目、每个参数的类型、以及参数如何传送等因素决定了应用程序特定的协议。有很多方法可以确定此类协议,但我相信最好的方法就是使用WSDL。如果我们用这种视角来看待它,WSDL不只是一种接口协议,而且是一种协议特定的语言。它就是我们超越"固定"协议(IP、HTTP等)所需要的应用程序特定协议。


  WSDL可以确定SOAP消息是否遵从RPC或文档风格。RPC风格的消息(就是示例中所用的)看起来像是函数调用。而文档风格的消息则更普通,嵌套层次更小。下面的XML消息就是示例WSDL文件解析后的发送/接受效果,解析使用的是MS SOAP Toolkit 2.0(MSTK2)中的SoapClient对象。


  从客户端调用"foo(5131953)"函数:


<?xml version="1.0" encoding="UTF-8" standalone="no"?>

 <SOAP-ENV:Envelope

  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"

  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">

 <SOAP-ENV:Body>

  <m:foo xmlns:m="http://tempuri.org/message/">

   <arg>5131953</arg>

  </m:foo>

 </SOAP-ENV:Body>

  </SOAP-ENV:Envelope>

 从服务器接受的信息:

  <?xml version="1.0" encoding="UTF-8" standalone="no"?>

<SOAP-ENV:Envelope

SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"

xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">

<SOAP-ENV:Body>

<SOAPSDK1:fooResponse xmlns:SOAPSDK1="http://tempuri.org/message/">

<result>5131953</result>

</SOAPSDK1:fooResponse>

</SOAP-ENV:Body>

</SOAP-ENV:Envelope>


  两函数都调用了消息,其回应是有效的XML。SOAP消息由几部分组成,首先是<Envelop>元素,包含一个可选的<Header>元素以及至少一个<body>元素。Rpc函数所调用的消息体有一个根据操作"foo"命名的元素,而回应信息体有一个"fooResponse"元素。Foo元素有一个部分<arg>,就和WSDL中描述的一样,是单参数的。fooResponse也相应的有一个<result>的部分。注意encodingStyle、envelope和message的namespace和WSDL Bindings栏中的预定义的一致,重复如下:


<binding name="SimpleBinding" type="wsdlns:SimplePortType">

<stk:binding preferredEncoding="UTF-8" />

<soap:binding style="rpc"

transport="http://schemas.xmlsoap.org/soap/http"/>

<operation name="foo">

<soap:operation

soapAction="http://tempuri.org/action/Simple.foo"/>

<input>

<soap:body use="encoded"

namespace="http://tempuri.org/message/"

encodingStyle=

"http://schemas.xmlsoap.org/soap/encoding/" />

</input>

<output>

<soap:body use="encoded"

namespace="http://tempuri.org/message/"

encodingStyle=

"http://schemas.xmlsoap.org/soap/encoding/" />

</output>

</operation>

</binding>