请问如果通过Web Service 传递链表对象?
十分感谢.
十分感谢.
解决方案 »
- blazingfire 还需要问您一个问题
- Delphi中构造函数的问题
- [菜鸟问题-银子不多,还请各位大侠多多包涵!]关于判断输入的数字字符在表中是否存在的问题?
- 我用DELPHI6来连接ACCESS时那个密码的问题处理不好
- ADO的查询问题
- 用ENTER键实现TAB键的功能
- 一个脑人的问题:程序运行后只在后台运行,如何才能让它露出真面目,请各位帮忙,程序如下
- 运行时出现的一个错误提示,请求帮助分析一下其出错原因
- 急。adoquery1.append之后。怎么才能让鼠标点一下就到我指定的行。
- ado的常见错误!'Either bof or eof is true,or the current...'
- 怎么取某一特定字符串的左边值?
- 一个特小问题!不过·还是有分!
来自:http://mental.mentsu.com/tech/delphi/d6_soap2.htmDELPHI 6 抢先研究-- BizSnap/SOAP/WebService 之二
-- 通过 SOAP 传递自定义类型数据
在前一个例子(见 《DELPHI 6 抢先研究 -- BizSnap/SOAP/WebService 之一 -- 一个 Hello world! 的例子》)中我们看到,通过 SOAP 可以很方便地进行远程对象调用,虽然那个例子用的对象是一个 Delphi 类,但实际上只需要对对象作一个 SOAP 包装,即可调用包括 COM/CORBA/EJB 等各种对象(除 EJB 必须用 Java 实现外, COM/CORBA 都已可以用 Delphi 实现)。在那个例子中,接口方法用到的数据类型都是标准类型,但实际应用中常常会碰到要传递自定义类型的情况,这时的操作略麻烦一些,详情如李维 《樂趣無窮,可能無限的新技術-Web Service》 一文中的例子所示。
同样,这里也要用一个例子来说明通过 SOAP 传递自定义数据类型的方法,这个例子会是一个比较麻烦的例子: 服务端:
1.New|WebServices|Soap Server Application ,如下图:
这个例子是用 Web App Debugger (详见《DELPHI 6 抢先研究 -- Web 应用开发及调试》), 设置其 CoClass Name 为 wadSoapDemo2 , 如下图:
2.SaveAll , Unit2 命名为: SvrWMMain , Unit1 不改名, Project1 命名为: Server ;
3.New|Data Module ,将此单元保存为 SvrDataMod ;
4.在其中放入两个 dbExpress 控件: SQLConnection1 和 SQLDataSet1 ,如下图:
其属性设置为: SQLConnection1 ConnectionName := IBLocal;
LoginPrompt := false;
Params.Values['Database'] := '[...]\Examples\Database\Employee.gdb';
// 上面的 [...] 为你的 InterBase 安装路径
SQLDataSet1 SQLConnection := SQLConnection1;
CommandText := 'select FULL_NAME, PHONE_EXT from EMPLOYEE WHERE EMP_NO = :EMP_NO'; 5.New|Unit ,将此单元保存为 SvrDataType ,其内容如下: unit SvrDataType;interfaceUses
InvokeRegistry;Type
TEmpInfo = Class( TRemotable )
Private
FName : String;
FPhone : String;
published
Property Name : String Read FName Write FName;
Property Phone : String Read FPhone Write FPhone;
end;implementationInitialization
RemClassRegistry.RegisterXSClass( TEmpInfo );Finalization
RemClassRegistry.UnRegisterXSClass( TEmpInfo );end. 此单元中定义了类: TEmpInfo ,用于记录员工信息,包括 Name 和 Phone 两个域,均为字符串类型。对于需要传递到客户端的数据类型,必须从 TRemotable 类派生,它能够自动处理类型信息的传递。如果要手工处理自定义数据类型的传递,则必须从 TRemotableXS 类派生,其用法与 TRemotable 类似,但这样的话,必须实现两个转换方法: NativeToXS 和 XSToNative ,详见 Delphi6\Source\Soap\XSBuiltIns.pas 中的几个类的实现。
需要注意的是,此类中将两个属性放在 Published 中,这里一定要这么做,我曾经因为将它们放在了 Public 中,导致客户端无法取得服务端的数据类型信息,后来才发现它们必须放在 Published 中才行,所以虽然这里并不是控件,这些属性也不是为了要在 Object Inspector 中显示,但仍然需要放在 Published 中。这可能是因为 Published 较 Public 多一些 RTTI(Run Time Type Info,运行时类型信息) 的东东,而远程数据类型是依赖于 RTTI 的。
最后是在远程类注册信息库中注册和反注册此类。 6.New|Unit ,将此单元保存为 SvrSoapIntf ,其内容如下: unit SvrSoapIntf;interfaceUses
InvokeRegistry, SvrDataType;Type
ISoapEmployee = Interface( IInvokable )
['{31903B5A-96B3-43C2-A7B5-F67F6DB829E5}']
Function GetEmployee( aEmpNo : Integer ) : TEmpInfo; StdCall;
End;implementationInitialization
InvRegistry.RegisterInterface( TypeInfo( ISoapEmployee ) );end. 此单元中定义了 SOAP 接口,这与前一个例子并没有大的不同,只是这次为了清晰起见,将此接口放在一个单独的单元里实现。唯一区别较大的是此接口中的方法 GetEmployee 返回了一个自定义数据类型: TEmpInfo 。 7.在 SvrWMMain 单元中加入 SOAP 实现类,完整的单元内容如下: unit SvrWMMain;interfaceuses
SysUtils, Classes, HTTPApp, WSDLPub, SOAPPasInv, SOAPHTTPPasInv,
SoapHTTPDisp, WebBrokerSOAP;type
TWebModule2 = class(TWebModule)
HTTPSoapDispatcher1: THTTPSoapDispatcher;
HTTPSoapPascalInvoker1: THTTPSoapPascalInvoker;
WSDLHTMLPublish1: TWSDLHTMLPublish;
private
{ Private declarations }
public
{ Public declarations }
end;var
WebModule2: TWebModule2;implementationuses WebReq, InvokeRegistry, SvrDataType, SvrSoapIntf, SvrDataMod;{$R *.DFM}Type
TSoapEmployee = class( TInvokableClass, ISoapEmployee )
Protected
Function GetEmployee( aEmpNo : Integer ) : TEmpInfo; StdCall;
End;