DELPHI 6 抢先研究-- BizSnap/SOAP/WebService 之一 - -- 一个 Hello world! 的例子

SOAP 技术号称 Microsoft 之梦,也是 Borland 给 Delphi 6 定下的最大卖点,在6月14日的 DELPHI 6 上海发布会(见 《 Delphi 6 上海发布会》 )上见识过才知道它的厉害。 SOAP 是我得到 Delphi 6 后最想研究的几项新技术之一, 但 Delphi 6 的帮助太不详细,仅有的那两个 DEMO 又太过复杂, 而且还不是基于 HTTP 的,只好自己研究, 最近这两天,总算有大突破,所以来此与大家分享。另外,李维后来也写了一篇文章介绍用 Delphi 6 做 Web Services , 见《樂趣無窮,可能無限的新技術-Web Service》


鉴于 DELPHI 6 自带的 DEMO 太复杂,我在这里写一个简单的 Hello World , 用 Windows98 + PWS 实现:


服务端:

1.New|WebServices|Soap Server Application ,如下图:

        <img width="443" height="365" src="/images/illustrations/d6_soap1ide1.jpg" alt=""/>
        <p>选 ISAPI/NSAPI Dynamic Link Library ,如下图: </p>

        <img width="317" height="254" src="/images/illustrations/d6_soap1ide2.jpg" alt=""/>
        <p>
          如果你想试试 DELPHI6 新增的 Web App Debugger,也可以选它,关于它请见 <a href="/root/entry.php?id=61">《DELPHI 6 抢先研究 -- Web 应用开发及调试》</a>); <br/></p><p>
          2.SaveAll , Unit1 命名为: MainWM , Project1 命名为: SoapTest ; <br/></p><p>
          3.在 MainWM 单元中的 Uses 中加入: InvokeRegistry 单元; <br/></p><p>
          4.自定义一个接口,及其对应类的实现,通常另建一个单元来放,但因为在客户端可以通过从 WSDL 导入接口的方法来产生一个接口单元,
          所以这里是放在 MainWM 单元里的: </p>
        <pre>  ISoapHello = Interface ( IInvokable )<br/>  ['{6DF34980-6FFC-11D5-9E62-0050BABD8FE1}']  //  这个GUID你自己用 Ctrl+Shift+G 产生<br/>    Function GetHello( aID : Integer ) : WideString; StdCall;<br/>  End;<br/><br/>  TSoapHello = Class ( TInvokableClass, ISoapHello )<br/>  Protected<br/>    Function GetHello( aID : Integer ) : WideString; StdCall;<br/>  End;<br/></pre>
        <p>5.实现 GetHello 函数: </p>
        <pre>Function TSoapHello.GetHello( aID : Integer ) : WideString;<br/>Begin<br/>  If ( aID = 1 ) Then<br/>    Result := 'Hello world!'<br/>  Else<br/>    Result := 'Error ID!';<br/>End;<br/></pre>
        <p>6.注册接口和类: </p>
        <pre>Initialization<br/>  InvRegistry.RegisterInterface( TypeInfo( ISoapHello ) );<br/>  InvRegistry.RegisterInvokableClass( TSoapHello );<br/></pre>
        <p>7.编译之即可产生: SoapTest.dll ; </p>
        <p>完成后的 IDE 如下图: </p>
        <img width="512" height="428" src="/images/illustrations/d6_soap1ide3.jpg" alt=""/>
        <p>启动 PWS ,设置虚拟目录 soap 为 soaptest.dll 所在的目录,权限为&ldquo;执行&rdquo;。打开浏览器,
          输入 URL 为:<br/></p><p>http://localhost/soap/soaptest.dll/wsdl <br/></p><p>即可看到一个表格,显示了此
          SOAP 服务(即所谓的 Web Service ) 所提供的 WSDL 其中应该有我们自定义的接口: ISoapHello ,点其链接将返回一个
          XML 文档, ISoapHello 就是用这个 XML 文档描述的。<br/></p><p><br type="_moz"/> </p>
        <p>客户端程序(补充:我这里的做法与李维在

《樂趣無窮,可能無限的新技術-Web Service》一文中的做法不同, 客户端程序完全不需要包含服务端的任何程序,唯一的接口单元也是从服务端的 WSDL 中导出 – Oct.20-01):

1.New|Application 新建一个一般 VCL 应用程序;

2.SaveAll , Unit1 命名为 ClnMain , Project1 命名为 SoapClient ;

3.New|Web Services|Web Services Importer ,如下图:

        <img width="443" height="365" src="/images/illustrations/d6_soap1ide4.jpg" alt=""/>
        <p>在下图中的URL中输入: http://localhost/soap/soaptest.dll/wsdl/ISoapHello, </p>

        <img width="420" height="338" src="/images/illustrations/d6_soap1ide5.jpg" alt=""/>
        <p>如果上面用浏览器可以看到正确的 XML 文档的话,这时确定后将产生一个单元,其中有我们在服务端定义的接口;

如果你细心的话将会发现其中那个 ISoapHello 接口的 GUID 与服务端并不相同;

4.SaveAll, Unit1 命名为 SoapIntf ,再在 ClnMain 中 Uses 加入 SoapIntf 单元;

5.在 Form1 上放上 Edit, Label, Button, HTTPRIO (在 WebServices 页中的第一个)四个控件,设置 HTTPRIO1.URL 为:

http://localhost/delphi6/soap/SoapTest.dll/soap

6.双击 Button1 输入下面的程序:

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

完成后的 IDE 如下图:

7.编译运行,在 Edit1 中输入"1"按 Button1 , Label1 将显示"Hello world!",输入其它数字将显示"Error ID!";


SOAP so easy.

Jun.20, Jul.29-01