本文整理自网络,侵删。
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中format与formatdatetime函数详解
更多相关阅读请进入《Delphi》频道 >>