在Delphi上通过POST发送和接收XML

时间:2016-01-06 14:17:25

标签: xml api delphi post https

我见过一些例子here以及如何使用Indy将数据发布到服务器,但我的问题是如何查看服务器提供的答案?

以下是我所拥有的,来自用户Bruce McGee,并稍微修改了一下:

function ExecuteAPI: string;
var
  lHTTP: TIdHTTP;
  lParamList: TStringList;
begin
  lParamList := TStringList.Create;
  lParamList.Add('<input type=text name=StoreName value="Hálitopuro Produtos">');
  lParamList.Add('<input type=text name=StoreID value="123456"> ');
  lParamList.Add('<input type=text name=Username value="Admin"> ');
  lParamList.Add('<input type=password name=Password value="Password123">');
  lParamList.Add('<input type=text name=method value="ReportView">');
  lParamList.Add('<input type=text name=ObjectID value="425">');
  lParamList.Add('<input type=text name=Par1 value="Category name">');
  lParamList.Add('<input type=text name=Par2 value="Ref/Name/Descr"> ');
  lParamList.Add('<input type=text name=Par3 value="false"> ');
  lParamList.Add('<input type=text name=Par4 value="false"> ');

  lHTTP := TIdHTTP.Create(nil);

  try
    Result := lHTTP.Post('https://www.rumo.com.br/sistema/adm/APILogon.asp', lParamList);
  finally
    lHTTP.Free;
    lParamList.Free;
  end;
end;

API声明服务器还返回XML,无论请求或结果是什么,但我如何查看它?例如,填写TMemo?

2 个答案:

答案 0 :(得分:4)

  

我已经看到了一些关于如何使用Indy将数据发布到服务器的示例

您没有正确填充TStringList。不要将实际的HTML标签存储在其中,只需将它们name=value对存储起来,例如:

lParamList.Add('StoreName=Hálitopuro Produtos');
lParamList.Add('StoreID=123456');
lParamList.Add('Username=Admin');
lParamList.Add('Password=Password123');
lParamList.Add('method=ReportView');
lParamList.Add('ObjectID=425');
lParamList.Add('Par1=Category name');
lParamList.Add('Par2=Ref/Name/Descr');
lParamList.Add('Par3=false');
lParamList.Add('Par4=false');
  

如何查看服务器提供的答案?

TIdHTTP.Post()会返回服务器对您的回复。为此目的,有两个重载版本的Post() - 一个将响应返回为String,另一个用原始响应字节填充TStream。你正在调用第一个,所以只需使用你想要的String,例如:

var
  XML: string;
begin
  XML := ExecuteAPI;
  // use XML as needed, for example:
  // Memo1.Text := XML;
end;

但是,据说......

  

API声明服务器还返回XML,无论请求或结果是什么

XML不是文本数据,它是带有文本元素的二进制数据。将XML视为二进制文件对于非ASCII字符的正确字符集处理非常重要。您应该使用TStreamPost(),然后将原始数据加载到实际的XML解析器中以进行进一步处理(因为我确定您最终会想要实际上根据回复的内容做一些事情,而不仅仅是看它,例如:

procedure ExecuteAPI(Response: TStream);
var
  lHTTP: TIdHTTP;
  lParamList: TStringList;
begin
  lParamList := TStringList.Create;
  try
    lParamList.Add('StoreName=Hálitopuro Produtos');
    lParamList.Add('StoreID=123456');
    lParamList.Add('Username=...');
    lParamList.Add('Password=...');
    lParamList.Add('method=ReportView');
    lParamList.Add('ObjectID=425');
    lParamList.Add('Par1=Category name');
    lParamList.Add('Par2=Ref/Name/Descr');
    lParamList.Add('Par3=false');
    lParamList.Add('Par4=false');

    lHTTP := TIdHTTP.Create(nil);
    try
      lHTTP.Post('https://www.rumo.com.br/sistema/adm/APILogon.asp', lParamList, Response);
    finally
      lHTTP.Free;
    end;
  finally
    lParamList.Free;
  end;
end;

var
  XML: TMemoryStream;
  Doc: IXMLDocument;
begin
  XML := TMemoryStream.Create;
  try
    ExecuteAPI(XML);
    XML.Position := 0;
    {Memo1.Lines.LoadFromStream(XML);
    XML.Position := 0;}
    Doc := TXMLDocument.Create(nil);
    Doc.LoadFromStream(XML);
  finally
    XML.Free;
  end;
  // use Doc as needed...
end;

如果您让TIdHTTP.Post()String的形式返回XML,TIdHTTP会尝试通过分析HTTP Content-Type标头来找出XML的字符集,也可能是XML自己的prolog声明,然后根据该charset将原始数据解码为Unicode,然后将Unicode数据重新编码为String(取决于Ansi或Unicode)在您的Delphi版本上)。第一步是容易出错并且可能导致数据丢失,例如,如果HTTP服务器配置错误。最好让TIdHTTP.Post()返回原始XML数据,让XML解析器处理字符集解码。这是其工作的一部分,毕竟。

答案 1 :(得分:2)

  

如何查看,例如填写TMemo?

要查看备忘录控件中的文本,请指定Text属性:

Memo1.Text := ExecuteAPI;
相关问题