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;  

http://blog.csdn.net/pcplayer/article/details/71914918

相关阅读 >>

Delphi多线程程序示例

isnumeric 判断字符串是否为数字

Delphi 自带rest调试工具 restdebugger 用法

Delphi base64加解密

Delphi 外挂编写的几个api函数

android实例-拍摄和分享照片、分享文本(xe8+小米2)

Delphi wmi 取硬件信息

Delphi整理八(对话框)

Delphi 回车符 换行符

Delphi wmi 获取网络信息

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



打赏

取消

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

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

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

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

评论

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