当前位置:网站首页>Delphi SOAP WebService 服务器端多个 SoapDataModule 实现相同的接口方法,接口继承

Delphi SOAP WebService 服务器端多个 SoapDataModule 实现相同的接口方法,接口继承

2022-07-04 20:34:00 pcplayer

场景

WebService 服务器端,为了方便代码管理,将不同的业务逻辑,分到不同的 TSoapDataModule 里面去。这样好对代码做模块化管理。

多个 TSoapDataModule 可能需要实现相同的接口方法,每个 TSoapDataModule 模块对该方法的实现代码可能不同(因为业务不同);最简单可能性是每个模块要检查的客户端访问权限不同。

那么,在客户端,因为是调用服务器端的不同接口的相同方法,如果给每个接口写一次方法调用,代码冗余。

解决办法

服务器端:服务器端的接口,默认(IDE 自动生成的代码)从 IAppServerSOAP 继承。

如果我要多个接口里面都有一个相同的方法(或函数),可以自己定义一个接口,从 IAppServerSOAP 继承。

务器端的所有接口,从一个父类接口继承。上述相同的接口方法,声明到这个父类接口里面。

如此一来,客户端只需要一个调用父类接口的方法,根据子类接口不同,实际调用到的服务器端的实现模块就不同。搞定!

以下代码测试通过。

代码 - 服务器端接口声明

IParientIntf = interface(IAppServerSOAP)
    ['{04E35D2B-4A63-45DE-98C0-AED830BB06B7}']
    function Hello(const S: string): string; stdcall;
  end;

  //ISoapDM_A = interface(IAppServerSOAP)
  ISoapDM_A = interface(IParientIntf)
    ['{4499D900-1856-4178-8D6E-617856DBE2BD}']
  end;

  //ISoapDM_B = interface(IAppServerSOAP)
  ISoapDM_B = interface(IParientIntf)
    ['{9618B6D7-0826-47D7-AAF6-F7BB3D6F1CDE}']
  end;

服务器端,模块一的代码:

TSoapDM_A = class(TSoapDataModule, ISoapDM_A, IAppServerSOAP, IAppServer)
    FDConnection1: TFDConnection;
    FDQuery1: TFDQuery;
    DataSetProvider1: TDataSetProvider;
    DataSetProvider11111: TDataSetProvider;
  private
  
  public
    function Hello(const S: string): string; stdcall;
  end;
  
function TSoapDM_A.Hello(const S: string): string;
begin
  Result := 'Hello, ' + S + '; This is SoapDM_AAAAA';
end;

务器端,模块二的代码:

TSoapDM_B = class(TSoapDataModule, ISoapDM_B, IAppServerSOAP, IAppServer)
    FDConnection1: TFDConnection;
    FDQuery1: TFDQuery;
    DataSetProvider1: TDataSetProvider;
    DataSetProvider222222: TDataSetProvider;
  private
  
  public
    function Hello(const S: string): string; stdcall;
  end;
  
function TSoapDM_B.Hello(const S: string): string;
begin
  Result := 'Hello, ' + S + '; This is SoapDM_B';
end;

客户端代码:

procedure TForm3.DoHello(Intf: IParientIntf; const S: string);
var
  S2: string;
begin
  S2 := Intf.Hello(S);
  ShowMessage(S2);
end;

客户端调用服务器端模块一:

procedure TForm3.Button3Click(Sender: TObject);
begin

  Self.DoHello(HttpRIO1 as ISoapDM_A, '你好');
end;

客户端调用务器端模块二:

procedure TForm3.Button2Click(Sender: TObject);
begin
  Self.DoHello(HttpRIO2 as ISoapDM_B, '深圳');
end;

上述调用,在客户端需要注意的问题:

同一个 HTTPRIO1 调用了接口一,再去调用接口二,会出现 interface not support 的异常;反之亦然。采用同一个 HTTPRIO1 先后调用2个不同的接口该如何处理?暂时没看到有什么方法。

解决办法:多个 HttpRIO 实例,每个实例对应一个接口。

因此,上述代码里面,一个是 HttpRIO1 ; 另一个是 HttpRIO2;

总结

Delphi 的 WebService 框架中,服务器端由 IDE 自动创建的 TSoapDataModule 的子类模块,有它自己的接口声明。这个接口,继承自 IAppServerSOAP;

我们可以声明一个自己定义的接口,比如 IParientIntf = interface(IAppServerSOAP)

然后手动修改 IDE 创建的代码,把模块的接口的继承父类,改为 IParientIntf;

通过这样的方式,可以简化客户端的代码,无需对应每个模块,都实现一段相同的调用代码。

原网站

版权声明
本文为[pcplayer]所创,转载请带上原文链接,感谢
https://blog.csdn.net/pcplayer/article/details/125574351