【发布时间】:2012-06-28 15:11:43
【问题描述】:
我正在使用 Delphi XE2 与相当大的 SOAP 服务进行通信。我已成功导入 wsdl,一切正常。但是,我发现自己编写了很多类似的代码。我想要一个调用我的网络服务的通用方法。我也发现很难像现在这样对我的代码进行多线程处理,因为我必须为每种类型的调用编写大量代码。
作为一个周末程序员,我远未精通 Delphi 的来龙去脉,但我认为我至少对 RTTI 有一定的了解,我认为必须使用它来做我想做的事。
Web 服务有大约 700 种不同的方法,这几乎就是问题所在。从 wsdl 生成的代码有如下方法:
function addPhone(const Params: addPhone): addPhoneResponse; stdcall;
function updatePhone(const Params: updatePhone): updatePhoneResponse; stdcall;
function getPhone(const Params: getPhone): getPhoneResponse; stdcall;
function removePhone(const Params: removePhone): removePhoneResponse; stdcall;
function listPhone(const Params: listPhone): listPhoneResponse; stdcall;
function addStuff(const Params: addStuff): addStuffResponse; stdcall;
function updateStuff(const Params: updateStuff): updateStuffResponse; stdcall;
...
... about 700 more of the above
基本上,可以处理大约 700 种不同类型的事物,并且它们都有 add、update、get、remove 和 list-methods。对于每个调用,都有一个相应的类用作 SOAP 请求的参数。如上所示,响应还有一个对应的类。
这些类看起来像(非常简化):
addStuff = class
private
FStuff: string;
published
property stuff: string Index (IS_UNQL) read FStuff write FStuff;
end;
所以当我调用网络服务时,例如:
procedure CreateStuff;
var
req: addStuff;
res: addStuffResponse;
soap: MyWebServicePort;
begin
// Use the function in the wsdl-generated code to create HTTPRIO
soap := GetMyWebServicePort(false,'',nil);
// Create Parameter Object
req := addPhone.Create;
req.stuff := 'test';
// Send the SOAP Request
res := soap.addStuff(req);
end;
(是的,我知道我应该尝试..finally 和 Free :-))
然后,在代码的其他地方我需要调用不同的方法:
procedure listStuff;
var
req: listStuff;
res: listStuffResponse;
soap: MyWebServicePort;
begin
// Use the function in the wsdl-generated code to create HTTPRIO
soap := GetMyWebServicePort(false,'',nil);
// Create Parameter Object
req := listPhone.Create;
req.stuff := 'test2';
// Send the SOAP Request
res := soap.listStuff(req);
end;
由于我知道参数始终是一个名称与我调用的方法等效的类,因此我希望能够执行以下元代码之类的操作,以便动态调用调用。我想这需要一些 RTTI 魔法,但我一直无法找到一种方法来做到这一点:
procedure soapRequest(Param: Something; var Response: Something);
begin
soap := GetMyWebServicePort(false,'',nil);
Response := soap.DynamicInvoke(Param.ClassName, Param);
end
然后我可以这样做:
soapRequest(VarOfTypeAddStuff,VarOfTypeAddStuffResponse)
soapRequest(VarOfTypeListStuff,VarOfTypeListStuffResponse)
...
有人知道如何简化我对网络服务的调用吗?
【问题讨论】:
-
看看是否有人提出这样的想法会很有趣,但我只是编写了包装例程,就像你必须“隐藏”细节一样。
-
@dahook:第一篇文章写得非常好。投票赞成。欢迎来到 SO。
标签: delphi soap delphi-xe2 rtti