通过名称动态地调用delphi-Call SOAP方法?

电脑杂谈  发布时间:2020-04-03 05:12:45  来源:网络整理

下载 文件 delphi_delphi idhttp 下载文件_delphi中soap协议下载文件

这是我在该论坛上的第一篇文章,我希望以正确的方式提出我的问题. 抱歉,长度不够,但是我发现很难缩减长度.

我正在使用Delphi XE2与相当大的SOAP服务进行通信. 我已经成功导入了wsdl,并且一切正常. 但是,我发现自己写了很多类似的代码. 我想要一个通用方法来调用我的Web服务. 我也很难多次读取代码,因为现在我必须为每种类型的调用编写大量代码.

更多的是周末程序员,我远远不掌握Delphi的导入和导出,但是我认为至少我对RTTI有很好的了解,我相信我应该习惯于做自己想做的事情.

p>

大约有700种不同的Web服务方法,这几乎是一个问题. 从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

delphi中soap协议下载文件_下载 文件 delphi_delphi idhttp 下载文件

基本上delphi中soap协议下载文件,可以处理大约700种不同类型的事物,包括添加,更新,获取,删除和列出方法. 对于每个调用,都有一个对应的类用作SOAP请求的参数. 如上所述,还有一个对应的响应类.

这些是相似的(非常简化):

addStuff = class
  private
    FStuff: string;
  published
    property stuff: string  Index (IS_UNQL) read FStuff write FStuff;
  end;

因此,当我调用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;

(是的,我知道我应该尝试,它是完全免费的,并且: -))

下载 文件 delphi_delphi中soap协议下载文件_delphi idhttp 下载文件

因此,在代码的其他地方,我需要调用其他方法:

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;

因为我知道此参数始终是一个类,所以它的名称等效于我调用的方法delphi中soap协议下载文件,因此我想进行一些动态调用,例如下面的元代码. 我认为这需要一些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)
...

delphi中soap协议下载文件_delphi idhttp 下载文件_下载 文件 delphi

有人知道如何简化对网络服务的呼叫吗?

预先感谢

Tan

这真的很奇怪. 我刚发布了一个问题. 我已经为自己工作了几周,突然间我就解决了自己……我受到周围SO的启发. 我发现这对我有帮助:

我的方案有点具体,因为我使用与方法本身具有相同类名的参数来调用该方法. 我还编写了一个更简单的版本来与公共Web服务进行通信. 如果有人感兴趣,您可以在此处获取代码: 这是一个无用的示例,因为仅当Web服务具有许多不同的方法时才执行动态方法调用. 但是,可能会有人感兴趣: -)

这是我解决网络服务的方式. 如上所述,这是非常具体的,并且代码可以更通用,但这对我有用.

delphi中soap协议下载文件_下载 文件 delphi_delphi idhttp 下载文件

使用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;

并使用以上功能:

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;

我有一些打字,但就我而言,我认为我会安全的. 有人还有其他意见/建议吗?我的意思是,这可行,但是可能有一些方法可以加强它.

干杯

Tan


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-162075-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...