Delphi WebService 中采用 TSOAPAttachment 传输文件


本文整理自网络,侵删。

 
Delphi 推出对 WebService 的支持很多年了。

遥想当年 XML, SOPA 火爆的时候,Delphi 也跟风推出了对 WebService 的支持。现在 JSON RESTful 火爆了,Delphi 又跟风推出了 DataSnap。

不过,我还是觉得 Delphi 的 WebService 采用的基于 Interface 的架构,代码更简单,优雅。不知道为什么 DataSnap 放弃了基于 Interface 的架构。莫非是 Delphi 的架构师换人导致的?

目前看来,做基于互联网的应用,还是用 WebService 的架构更简单。DataSnap 的架构比较复杂麻烦。唯一的好处可能是目前如果要支持一些 HTML 网页客户端的 JS 的话,服务器端必须要输出 RESTful 的 JSON,要用 delphi 来开发服务器端,只得用 DataSnap 架构了。

废话少说,回到 WebService。在使用 WebService 的时候,如果客户端和服务器端之间需要传递文件 -- 任何编码的二进制文件,比如图片、视频,等等,上传或者下载,有几个不同的方法。先说两个土办法:

1. 做一个 WebService 的接口函数,里面的参数是字符串。把二进制文件编码为 BASE64 格式的字符串以后,调用接口函数的方式来在服务器和客户端之间传输。

2. 直接把二进制文件的数据,写入数据库的 Blob 字段,直接利用 Delphi 的接口函数可以传递 Variant 格式参数的功能,搞一个接口函数,传递 ClientDataSet.Data 这个 Variant。

2.1. 或者直接利用 Delphi WebService 支持的 ISoapAppServer 接口,一行代码不写,把数据库的 Data 从服务器端传递到客户端的 ClientDataSet 或者反过来传。

但是,标准的办法,应该是利用 WebService 的 TSOAPAttachment。因为既然是基于 WEB 的东西,当然应该利用 WEB 架构现成的 Web Attachment 了。



在 Delphi XE 之前,Delphi 写的 WebService 使用 TSOAPAttachment 的方式来传递文件(其实就是 WEB 的附件,或 EMAIL 的附件,因为 Delphi TSOAPAttachment 是 MIME编码的),在 CGI 或 ISAPI 模式下是没有问题的,但独立 WEB 服务器模式下有问题。估计是当时依赖的 Indy HTTP Server 有问题。

现在,Delphi 创建一个 WebService Server 的时候,如果选择独立服务器模式,它创建的工程,依然内置了 Indy HTTP Server,经过测试,在 Delphi 10.2 上面,已经可以正常工作。

我写了一个测试例子代码,测试通过。打包放在了 CSDN 的资源下载里面。需要的可以去用我的 ID 搜索。地址:http://download.csdn.net/detail/pcplayer/9841819



服务器端代码片段如下:

unit TestAttachImpl;
 
interface
 
uses Soap.InvokeRegistry, System.Types, System.SysUtils, Soap.XSBuiltIns, TestAttachIntf;
 
type
 
  { TTestAttach }
  TTestAttach = class(TInvokableClass, ITestAttach)
  public
    procedure GetAttach(var FileName: string; out Attach: TSOAPAttachment); stdcall;
    procedure PutAttach(const FileName: string; Attach: TSOAPAttachment); stdcall;
  end;
 
implementation
 
 
{ TTestAttach }
 
procedure TTestAttach.GetAttach(var FileName: string; out Attach: TSOAPAttachment);
var
  Fn: string;
begin
  //下载文件给客户端
  Fn := 'F:\H264Output.mp4';
 
  Attach := TSOAPAttachment.Create;
  Attach.SetSourceFile(Fn);
  FileName := ExtractFileName(Fn);
end;
 
procedure TTestAttach.PutAttach(const FileName: string;
  Attach: TSOAPAttachment);
begin
  //客户端上传附件
  Attach.SaveToFile(ExtractFilePath(GetModuleName(0)) + FileName);
end;
 
initialization
{ Invokable classes must be registered }
   InvRegistry.RegisterInvokableClass(TTestAttach);
end.


客户端代码片段如下:

procedure TForm2.Button1Click(Sender: TObject);
var
  Attach: TSOAPAttachment;
  Intf: ITestAttach;
  Path, Fn: string;
begin
  //下载文件
  Path := ExtractFilePath(Application.ExeName);
  Attach := TSOAPAttachment.Create;
  Intf := HTTPRIO1 as ITestAttach;
  try
    Intf.GetAttach(Fn, Attach);
    Attach.SaveToFile(Path + Fn);
  finally
    Intf := nil;
    Attach.Free;
  end;
 
end;
 
procedure TForm2.Button2Click(Sender: TObject);
var
  Fn: string;
  Attach: TSOAPAttachment;
  Intf: ITestAttach;
begin
  //上传文件
  if OpenDialog1.Execute then
  begin
    Fn := OpenDialog1.FileName;
 
    Attach := TSOAPAttachment.Create;
    Attach.SetSourceFile(Fn);
    Intf := HTTPRIO1 as ITestAttach;
    try
      Intf.PutAttach(ExtractFileName(Fn), Attach);
    finally
      Intf := nil;
      Attach.Free;
    end;
  end;
end;

――――――――――――――――

原文链接:https://blog.csdn.net/pcplayer/article/details/71914918

相关阅读 >>

Delphi bmp转换png

Delphi firedac 获取 insert 记录的自增 id

crc32.pas 第二版

Delphi dbnavigator1 模拟点击

Delphi跨平台的字符串代码标准

[Delphi]钩子(hook)机制的使用

Delphi 类和对象

Delphi olevariant excel保存文件

Delphi string转unicode

Delphi 得到字符串拼音首字母

更多相关阅读请进入《Delphi》频道 >>



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...