李维的 Demo 中,两个可以改进的地方

李维这次的内地之行(见《感受李维》一文)可以说在Borland 的用户掀起了一场风暴,在几个比较大的程序员论坛上,这是这几最热门的话题之一,我在 CSDN 上发了一贴关于他上海之行的文字,结果成为我发过的有史以来反响最强的一个贴子。

在这次 Borland 举办的 WebService 技术研讨会上,李维做了几个 Demo 来演示 Borland 的 WebService 解决方案,这是几个非常好的 Demo ,它们以一种很简单的方式,较为全面地展示了用 Borland 的几个主要产品进行 SOAP/WebService 开发的实现,但是我认为其中还是有两个地方可以改进。


第一个可以改进之处:


李维也是用打了 Update 2# 的 Delphi 6,这个版本的 Delphi 6 在 SOAP/WebService 应用开发方面有比较大的改进(见《DELPHI 6.02 抢先研究 -- BizSnap/SOAP/WebService 之四》一文),其中最大的改进之一便是 WSDL Import Wizard 。新的 WSDL Import Wizard 主要改进在:

  1.  增加了一个导入结果查看界面,可以以树形显示导入的 WSDL 中所含的接口内容,并且可以预览生成的接口单元;
  2. 生成的接口单元包含了 HTTP 远程接口对象生成;
  3. 支持新的 SOAP 标准,可以导入 Visual Studio.net 生成的 WSDL。 

而上述几点中的第二点就是李维可以改进的一点。在《DELPHI 6 抢先研究 -- BizSnap/SOAP/WebService 之一》一文的例子中所采用的方法就是李维的 Demo 中所用的方法,即放上一个 HTTPRIO 控件,设置好 URL 属性,再用如下的代码来访问远程接口:

Var
p : ISoapHello;
begin
p := HTTPRIO1 As ISoapHello;
Label1.Caption := p.GetHello( StrToInt( Edit1.Text ) );
end;

但是因为前面所说的 WSDL Import Wizard 的第二点改进,所以已经可以不用这么麻烦了,不需要再放 HTTPRIO 控件,而且代码也简单得只要一句:

  Label1.Caption := GetISoapHello.GetHello( StrToInt( Edit1.Text ) );

其中的 GetISoapHello 是一个函数,返回一个实现 ISoapHello 远程接口的对象,在导入 WSDL 时生成的接口单元文件里定义并实现的,它的功能就是新建一个 HTTPRIO 对象,并根据 WSDL 设置好所有的属性。


第二个可以改进之处:


这个和 SOAP/WebService 没有关系,只是我个人认为是他的 Demo 的一个瑕疵。在一个 Demo 中,他把通过 SOAP 收到的一个 Blob 字段的内容存到一个内存流(TMemoryStream)中准备显示在一个 TImage 控件上,但是因为 TImage 的 Picture 属性没有可用的 LoadFromStream 方法(虽然有,但是不是 Public 的),所以他用如下的代码,先保存到一个临时文件里再用 LoadFromFile 来显示:

  ms.SaveToFile( 'temp.bmp' );
Image1.Picture.LoadFromFile( 'temp.bmp' );

其中 ms 是 TMemoryStream 对象, Image1 是要用于显示的 TImage 控件。这种方法不是不行,但我觉得不太好,因为仅仅是这个原因而用文件来作中转实在是一种比较笨的方法,我认为在这种情况下用一个 TBitmap (如果是 JPEG 格式就用 TJPEGImage )对象来代替文件会比较好一些,如下:

  bmp := TBitmap.Create;
bmp.LoadFromStream( ms );
Image1.Picture.Assigned( bmp );
bmp.Free;

其中 bmp 是一个 TBitmap 对象。