dah*_*ook 14 delphi soap rtti delphi-xe2
我正在使用Delphi XE2与相当大的SOAP服务进行通信.我已经成功导入了wsdl,一切正常.但是,我发现自己编写了很多类似的代码.我想有一个调用我的Web服务的通用方法.我也发现很难像现在这样多线程化我的代码,因为我必须为每种类型的调用编写这么多代码.
作为一个周末程序员,我远远没有掌握德尔福的进出,但我认为我至少对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
Run Code Online (Sandbox Code Playgroud)
基本上,大约有700种不同类型的东西可以处理,并且它们都有添加,更新,获取,删除和列表方法.每次调用时,都有一个相应的类,用作SOAP请求的参数.如上所示,还有一个相应的响应类.
这些类看起来像(非常简化):
addStuff = class
private
FStuff: string;
published
property stuff: string Index (IS_UNQL) read FStuff write FStuff;
end;
Run Code Online (Sandbox Code Playgroud)
所以,当我调用Web服务时,我会这样做:
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;
Run Code Online (Sandbox Code Playgroud)
(是的,我知道我应该尝试..最终和免费在那里:-))
然后,代码中的其他地方我需要调用另一个方法:
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;
Run Code Online (Sandbox Code Playgroud)
因为我知道参数总是一个名称与我调用的方法相同的类,所以我希望能够执行类似下面的元代码来动态调用调用.我想它需要一些RTTI魔法,但我还没有找到办法:
procedure soapRequest(Param: Something; var Response: Something);
begin
soap := GetMyWebServicePort(false,'',nil);
Response := soap.DynamicInvoke(Param.ClassName, Param);
end
Run Code Online (Sandbox Code Playgroud)
然后我可以这样做:
soapRequest(VarOfTypeAddStuff,VarOfTypeAddStuffResponse)
soapRequest(VarOfTypeListStuff,VarOfTypeListStuffResponse)
...
Run Code Online (Sandbox Code Playgroud)
有没有人知道如何简化我对Web服务的调用?
真的很奇怪,我发布了一个我几周来一直试图解决自己的问题后几个小时,突然就自己解决了......我受到环顾四周的启发,我发现这个一路上帮助我:Delphi - Invoke Record method per name。
我的场景有些具体,因为我使用与方法本身具有相同类名的参数来调用方法。我还编写了与公共网络服务通信的更简单的版本。如果有人感兴趣,您可以在这里获取该代码: http: //www.hook.se/delphi/SoapDynamicInvoke.zip。这是一个无用的示例,因为仅当 Web 服务具有许多不同的方法时,进行动态方法调用才有意义。尽管如此,某些人可能会感兴趣:-)
下面是我如何为我的网络服务解决这个问题。如前所述,它非常具体,代码可以变得更通用,但这对我有用。
使用 TRemotable 对象调用此方法,然后使用与该对象的类名同名的方法调用 Web 服务。
function soapRequest(Param: TRemotable): TValue;
var
soap: AXLPort;
C: TRttiContext;
T: TRttiType;
M: TRttiMethod;
SoapParam: TArray<TValue>;
TVres: TValue;
soap: MyWebServicePort;
begin
// Use the function in the wsdl-generated code to create HTTPRIO
soap := GetMyWebServicePort(false,'',nil); C := TRttiContext.Create;
T := C.FindType('MyWebService.MyWebServicePort');
M := T.GetMethod(Param.ClassName);
SetLength(SoapParam,1);
SoapParam[0] := TValue.From(Param);
TVres := M.Invoke(TValue.From<IInterface>(soap), SoapParam);
Result := TVres;
end;
Run Code Online (Sandbox Code Playgroud)
并使用上面的函数:
procedure DoSomeSoapCalls(Sender: TObject);
var
req1: getStuff
res1: getStuffResponse;
req2: addStuff;
res2: addStuffResponse;
res: TValue;
begin
//Request #1
req1 := getStuff.Create;
req1.stuffToGet := 'abc';
try
res := soapRequest(req1);
res1 := getStuffResponse(res.AsObject);
finally
req1.Free;
end;
Writeln(res1.someproperty);
FreeAndNil(res1);
//Request #2
req2 := addStuff.Create;
req2.StuffToAdd := 'cde';
try
res := soapRequest(req2);
res2 := addStuffResponse(res.AsObject);
finally
req2.Free;
end;
Writeln(res2.result);
FreeAndNil(res2);
end;
Run Code Online (Sandbox Code Playgroud)
有必要进行一些类型转换,但就我而言,我认为这样做是非常安全的。还有人对此有任何其他意见/建议吗?我的意思是,这可行,但可能有方法可以增强它。
干杯,
担
| 归档时间: |
|
| 查看次数: |
2352 次 |
| 最近记录: |