Delphi(程序人生)

Delphi Programer DoubleCat

导航

从Interface到COM+(SOAP WebService)

InterfaceCOM+(SOAP WebService)

前言:

当你把一个函数定义在方法内部,那这个函数只能供这个方法使用。你把一个函数定义在单元的实现部份,那么这个函数只能供在此代码之后的所有方法使用。

当你把一个函数定义在单元接口内,那么整个单元内的方法都可以使用,引用这个单元的其它单元内方法也可以使用。

C++或其它开发工具想使用你这个函数时,你有二种选择,把这个函数封装成DLL或封装成COM,输出这个函数功能。

以上的这些情况,都只能在本机使用,最多只能在局域网内使用,如果你想定义一个方法,全球都能用,那怎么办?除了使用WebService你没有其它选择。

一、从InterfaceàCOMàCOM+àDCOMàSOAP WebService这些技术是层层推进,一环扣一环的,前者是后者的依赖基础,后者是从前者发展衍生出来的。

二、什么是SOAP WebService?他们是解决什么问题的?怎么用?

1、什么是SOAP,它与WebService是个什么关系?

SOAP是肥皂,当然这是不是肥皂的意思,SOAP=Sample ObjectAccess Protocol(简单对象访问协议),它是一个Write Protocol(写协议)

②因为它是个写协议,所以他必须以HTTP(超文本传输协议)做为载体,进行通信。

③ SOAP是个带写协议的数据封包,这个封包里面的内容格式是标准的XML,里面定义了要获取哪个功能服务。

④、WebService接受并解析SOAP封包,然后去查找SAOP封包所需服务的具体实现,WebService所提供的服务都是以接口形式编写的,所认要获取它的服务,必须通过接口进行调用。

⑤、SOAPWebService是不可分开的讲的,他们是一体的。

⑥、当WebService找到相应的服务调用成功后,把结果同样封装成一个SOAP数据包返回给客户端。

⑦、WebService能提供什么服务,客户端不知道,这时客户端只要连接到一个WebServiceWebService就会使用一个叫WSDL的标准输出接口(WSDL=Web Service Description Language Web服务描述语言)把WebService的所有服务功能封装成XML格式的SOAP包返回给客户端。

 如何建立一个WebService?

FileàNewàOtheràWebServiceàSOAP Service Application这时向导会放你要创建哪种类型的WebService,选择哪一种都可以,他们之间可以互相转换,为了方便调试一般建立Web App Debugger类型的WebService。这时向导会问询是否创建WebService模块和相对应的接口单元与实现单元,一般选择是。这时在WebService Module中会自动加入三个组件,HTTPSOAPDispathcher,它是SOAP调度器,会拦截HTTPSOAP封包的请求,解析SOAP封包,把SOAP中的请求分泒给HTTPSoapPascalInvoker,HTTPSoapPascalInvoker根据得到的请求,激活WebService中的相应服务。获得服务后的内容,由WSDLHTMLPublish负责把结果封包成HTML返回给客户端。WSDHTML有一个属性AdminEnabled把它设为True就可以在IE查看WebService提供的服务清单.(如果手工调Web App Debugger)Delphi2007及以后的版本需要手动启动Bin下的ServerInfo.exe,调试用Tools->Web App Debugger,注意必须先启动ServerInfo.exe

如下是WebService的服务器代码,这段代码很简单就是输出一行信息.

接口单元代码

{ Invokable interface ImyShowMessage }

unit myShowMessageIntf;

interface

uses InvokeRegistry, Types, XSBuiltIns;

type

 { Invokable interfaces must derive from IInvokable }

 ImyShowMessage = interface(IInvokable)

 ['{3B31C8F5-725D-470A-89CF-02D881356905}']

    function theShowMessage():string;stdcall;//为了让其它语言开发工具调用,必须使用StdCall;方法最好使用函数,而不使用过程

    { Methods of Invokable interface must not use the default }

    { calling convention; stdcall is recommended }

 end;

implementation

initialization

 { Invokable interfaces must be registered }

 InvRegistry.RegisterInterface(TypeInfo(ImyShowMessage));

end.

实现单元代码

{ Invokable implementation File for TmyShowMessage which implements ImyShowMessage }

unit myShowMessageImpl;

interface

uses InvokeRegistry, Types, XSBuiltIns, myShowMessageIntf;

type

 { TmyShowMessage }

 TmyShowMessage = class(TInvokableClass, ImyShowMessage)

 Public

    function theShowMessage():string;stdcall;//为了让其它语言开发工具可以调用,最好使用Stdcall对方法进行后指示。

 end;

implementation

{ TmyShowMessage }

function TmyShowMessage.theShowMessage: string;

begin

   Result := 'I Love Delphi';

end;

initialization

{ Invokable classes must be registered }

   InvRegistry.RegisterInvokableClass(TmyShowMessage);

end.

Form单元代码

unit Unit1;

interface

uses

 SysUtils, Classes, Forms;

 

type

 TForm1 = class(TForm)

 private

    { Private declarations }

 public

    { Public declarations }

 end;

 

var

 Form1: TForm1;

 

implementation

 

uses SockApp;

{$R *.dfm}

 

initialization

 TWebAppSockObjectFactory.Create('Demo')

 //对像工厂创建的实例,这个名字在调用时必须使用到

end.

下面讲解,如何调用这个WebService

1,调用很简单,建一个普通工程,在Form上加入WebServiceàHTTPRIO组件。HTTPRIO这个组件,它可以直接连接到WebService并读取相应的服务

在这里说说HTTPRIO组件的URL属性与WSDLLocation属性。

1,     如果WebServiceDelphi开发的,那么使用HTTPRIOURLWSDLLocation属性与WebService连接,只要连接成功,可以在Service属性中选择相应的接口服务,在Port属性中可以选择相应的接口的端口。

2,     如果WebService不是Delphi开发的,那只能用WSDLLocation属性与WebService连接,连接成功在Service属性中选择相应的接口服务,在Port属性中选择相对的接口端口。

3,     URL里面用的是SOAP路径,在WSDLLocation中用的是WSDL路径,如何查看WSDL可以用IE打开一个WebService

4,     如,URL是这样写的http://localhost:8081/Project1.demo/soap注意EXE文件的后缀名为建立WebService时的coClass名称+SOAP就行了。WSDLLocation是这样写的http://localhost:8081/Project1.Demo/wsdl/ImyShowMessageEXE文件的后缀名为建立WebService时的coClass名称+wsdl+指定接口服务名称。如果是CGIISAPI就直接是WebService文件名,而没有coClass名称。

调用时:如果WebServiceDelphi开发的,把创建WebService时产生的接口文件加到客户端工程中,在Form单元中引用就行,如果是其它语言开发的,那就用FileàNewàOtheràWebServiceàWSDL Import向导导入 如图

如下是调用WebService的客户端代码

unit Unit3;

interface

uses

 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

 Dialogs, InvokeRegistry, Rio, SOAPHTTPClient, StdCtrls;

type

 TForm3 = class(TForm)

    HTTPRIO1: THTTPRIO;

    Button1: TButton;

    Edit1: TEdit;

    procedure Button1Click(Sender: TObject);

 private

    { Private declarations }

 public

    { Public declarations }

 end;

var

 Form3: TForm3;

implementation

uses myShowMessageIntf;//这里引用的是WebService的接口单元

{$R *.dfm}

procedure TForm3.Button1Click(Sender: TObject);

begin

 Edit1.Text := (HTTPRIO1 as ImyShowMessage).theShowMessage;

end;

initialization

end.

虽然这个例子没有什么实际应用,但是把WebService的原理是讲的比较清楚的

注意:IIS7启用CGIISAPI的方法如下:

Default Web Siteà处理程序映射àCGI EXEà右边编辑权限à执行打勾。如果没有看到这个功能那么增加方法如下:控制面板à程序à打开或关闭Windows功能àIIS相关的东西选上。这样处理后,把CGIISAPI类型的WebServer文件放到wwwRoot目录下,用IE可以看到SOAPWSDL内容,如:http://localhost/Project1.exe/wsdl/ImyShowMessage,在这里就不需要端口号了.

 ------------------------------------------------------------------

上面讲解是的如何把方法做到WebService里,下面讲解WebService与数据库的结合,这是WebService应用的重点

一、     如何建立一个数据库应用的WebService?

1FileàNewàOtheràWebService->SOAP Server Application,选择WebService服务器类型,如果是纯数据库服务器,不带方法输出,在创建向导问询是否Create Interface for SOAP module时,选择,no就行,如果又要带方法服务,那就选择yes。这样的创建与创建方法服务的WebService是一样的,只是没带接口单元文件与接口的实现单元文件。同样Web Module模块中自动加入三个组件HTTPSOAPDispatchHttpSoapPascalInvoker,WSDLHtmlPublish,把WSDLHTMLPublishAdmin Enable 属性设为True

2,创建WebService数据库服务模块,FileàNewàOtheràWebServiceàSOAP Server Data Moduleà这是创建向导会要求输入数据库模块名称(Module Name)。注意,这个模块名称就是对外提供数据库服务的接口名称,客户端连接WebService时,必须要使用到这个名称。按我的习惯,一般把这个模块命名为DM

3,到了这里,就象开发一般的应用数据库软件一样,把所有连接都放在这个DM文件里,注意,这里不放DataSource组件,每个数据库访问管道都配上一个DataSetProvider,客户端用的ClientDataSet只能挂接到这个DataSetProvider上访问后台数据库(访问的意思包括数据读取与数据写入)。一般DataSetProvider组件的AllowMultiRecordUpdates(允许多行记录同时更新,这个属性不是必须为true的)属性设为TrueAllowCommandText(允许在DataSetProvider上下达SQL语句,这个属性是必须设为true的,否则ClientDataSet上的SQL语句传过来后无法执行)属性设为True

5,     下面讲解如何连接数据库的WebService

6,     建立一个一般的Form,加入SOAPConnection组件。设置URLURL里设的是SOAP,不是WSDL)。URL的写法是HTTP://WebSerice/WebService应用程式名称/SOAP/SOAP数据模块接口。如果是WAD的话,WebService应用程式名改为WebService应用程式名称.coClass名称,调试WAD时一定要让Web App Debugger这个服务程式运行,否则ClientDataSet解析不到ProviderName里面的名称。URLf地址如:http://localhost:8081/P_WebServiceData.DataBaseTest/SOAP/IDM。再加入一个ClientDataSetRemoteServer属性挂接SOAPConnection组件。只要URL地址没有错误,在ProviderName属性里就可以把WebService中的数据模块中的DataProvider组件名称全部解析过来,然后选择要连接哪个DataProvider,这样连接任务就完成了,剩下的就是数据库开发部份了。

 

 

posted on 2011-04-01 20:59  DoubleCat  阅读(699)  评论(0编辑  收藏  举报