虽然关于SOAP的实现目前有很多种,但是我认为对于VC/VB程序员来说,选择Microsoft的实现是最好的。先撇开.NET的WebServices的底层库不谈(因为还不熟悉L),我们现在要讨论的是Microsoft Soap Toolkit 2.0。
Microsoft Soap Toolkit 2.0提供了一整套的COM对象来处理与SOAP相关的所有数据,可以让你在不了解SOAP和XML的情况下(当然最好还是了解的啦),也可以很容易和方便的使用任何一种编程语言来编写SOAP应用。你看到的,就是一个个的COM对象(符合微软的风格,符合一般程序员的编程习惯)。
一. 功能简介:
1. 提供了客户端的组件,可以让你指定WSDL,然后轻松调用对应的Web Service。
2. 提供了服务端的组件,可以让你指定WSDL、WSML和COM对象,自动为你生成Web Service。
3. 还提供了底层的处理组件,可以让你操纵SOAP消息的具体创建、处理和传输的过程。
二. 几个概念:
WSDL(Web Services Description Language):用于描述服务端所提供服务的XML格式。WSDL文件里,描述了服务端提供的服务,提供的调用方法,以及调用时所要遵循的格式,比如调用参数和返回值的格式等等。WSDL 很像COM编程里的IDL(Interface Description Language),是服务器与客户端之间的契约,双方必须按契约严格行事才能实现功能。
WSML(Web Services Meta Language): 用于描述WSDL里提供的方法与实现该方法的COM对象之间的映射关系。该文件是Microsoft的实现中特有的,不是SOAP标准的一部分。一般情况下,该文件只在服务端存在。
SOAP消息:客户端和服务端之间的方法调用请求和结果返回值都放在这些消息里,是XML格式的数据。
三. Web Service调用过程:
客户端:取得服务端的服务描述文件WSDL,解析该文件的内容,了解服务端的服务信息,以及调用方式。根据需要,生成恰当的SOAP请求消息(指定调用的方法,已经调用的参数),发往服务端。等待服务端返回的SOAP回应消息,解析得到返回值。
服务端:生成服务描述文件,以供客户端获取。接收客户端发来的SOAP请求消息,解析其中的方法调用和参数格式。根据WSDL和WSML的描述,调用相应的COM对象来完成指定功能,并把返回值放入SOAP回应消息返回给用户。
四. 编程的两种模式
高层接口
使用高层接口,你不需要知道SOAP和XML的任何信息,就可以生成和使用一个WebService。Soap Toolkit 2.0通过提供两个COM对象――SoapClient和SoapServer,来完成这些功能。
在客户端,你只需要生成一个SoapClient实例,并用WSDL作为参数来调用其中的mssoapinit方法。SoapClient对象会自动解析WSDL文件,并在内部生成所有Web Service的方法和参数信息。之后,你就可以像调用IDispatch接口里的方法一样,调用里面所有的方法。在VB或是脚本语言里,你甚至可以直接在SoapClient对象名后面直接加上.方法(参数…)进行调用。
在服务端,有两种处理模式。一种是生成ASP文件;另一种是直接使用ISAPI扩展,让Soap Toolkit提供的DLL来处理对WSDL的请求。
在第一种模式中,你需要在ASP文件里创建SoapServer对象,并用WSDL和WSML作为参数来调用Init方法,SoapServer在内部会自动建立相关的映射关系。然后,用ASP的Request和Response对象作为参数调用SoapInvoke方法。SoapServer会自动从Request里取得用户的SOAP请求消息,并解析,调用相应的COM完成功能,把返回值封装成SOAP回应消息,通过Response对象返回。
在第二种模式中,Soap Toolkit提供的ISAPI扩展会自动完成以上ASP模式的全部操作。
两种模式的比较是,第一种比较灵活,但是速度比较慢。而第二种虽然灵活性没有了,但是性能却很高。所以,如果没有特殊都请使用ISAPI模式。
低层接口
要使用低层接口,你必须对SOAP和XML有所了解。你可以对SOAP的处理过程进行控制,特别是要做特殊处理的时候。
在客户端,首先要创建一个HttpConnector对象,负责HTTP连接。设定Connector的一些头部信息,比如EndPoinURL和SoapAction等。如果网络连接需要使用代理服务器,那也要在这里设定相关的信息。接着创建SoapSerializer对象,用于生成Soap消息。按照WSDL里定义,把所有参数按顺序序列化,得到一个完整的SOAP请求消息。该Soap消息,作为Payload通过HttpConnector被发送到服务端。最后,生成一个SoapReader对象,负责读取服务端返回的SOAP消息,取得其中的返回值。
在服务端,首先通过ASP里的Request和Response对象取得HTTP连接的输入与输出。接着创建SoapReader对象,读取Request对象里的Soap请求消息,解析出要调用的方法和调用的参数, 执行实际的调用,并取得执行结果。最后,生成一个SoapSerializer对象,按照WSDL的描述,序列化执行结果,生成Soap回应消息,通过Response对象返回给客户端。
五. 疑问与解答
为什么要有WSML?
答:因为SOAP本身只是对象访问的协议,至于实现的方式并没有指定。一般来说,使用SOAP就是把现有系统的功能以标准的方式对外公开,让外部能够访问。而在微软的平台上,为了模块的互用性,功能的实现一般是以COM的方式提供的。而如何能够把WSDL里描述的方法,映射到COM的接口方法上,这就是WSML所要做的。现在你可以看到,使用WSML,你不需要做太多工作,就可以把现有的应用很快的变成Web Service应用。在服务端,你完全保留了Microsoft的COM/COM+应用模式。(当然,WSML也不是必须的,如果你不需要使用COM的方法映射。如果你不使用Soap Toolkit的高层接口,而使用底层接口。那就没有必要了。)
如何处理复杂的数据类型?
答:你可以自己实现一个自定义的类型映射COM对象(Custom Type Mapper),并在WSML里进行指定。这样,Soap Toolkit在处理过程当中,会调用这个Mapper对SOAP消息里的消息进行处理。比如要返回一个复杂数据,在服务端,Toolkit要懂得如何把一个复杂数据类型序列化为XML节点。而在客户端,Toolkit要懂得如何把XML节点重新表示为一个复杂的数据结构。
需要说明的是,这个映射对象(Mapper)并不是必须的,只是为了使用的方便而使用。也就是说,双方只要严格遵循WSDL里描述的规范,就一定能够达到调用成功。而不管你客户和服务端是如何映射这个复杂数据类型的,是一个C结构体也好,是一个COM对象也好,或是一个Java的类也好,都是无关紧要的。
六. 关于Soap Toolkit的例子
Toolkit自带的例子已经非常全面,解释了使用这个Toolkit需要了解的各种调用方式。通过看微软提供的代码,并亲自运行一遍,就会对该Soap Toolkit有比较感性的认识了。
不过,需要提醒你的是,要能正确运行附带的例子,你必须安装有IIS服务,并且还要根据要求创建虚拟目录和映射主机名。具体请参见Sample页的安装说明(Setup Instructions)。
七. Soap Toolkit的两个工具
WSDL Generator: 该工具是Toolkit自带的,主要的功能就是可以把一个COM对象作为一个Web Service发布,用于服务端的开发。
你只要指定了COM对象以及要输出的接口函数,和发布的网址等信息,该工具就会自动生成对应的WSDL和WSML文件。你只要把WSDL和WSML拷贝到对应的虚拟目录下,一个Web Service就完成了----该工具避免了手动书写WSDL和WSML的麻烦,但是由于该版本还无法实现复杂数据类型的映射。所以如果有复杂数据类型的情况,你还是要手动修改的。
Web Service Proxy Wizard: 该工具是在Toolkit之后才发布的,所以你需要单独下载(地址见附录)。该工具完成的功能正好与WSDL Generator相反,是为一个WSDL文件生成相应的COM访问对象,用于客户端的开发。
你只要指定要调用WebService的WSDL文件,该工具就会自动生成一个ATL的COM对象类(Proxy对象)。而通过调用生成的Proxy对象,就可以实现对Web Service的调用。而在这个Proxy对象里,是通过调用Soap Toolkit的底层接口来完成整个的Soap调用过程的。而且,由于生成的是一个V