首页 > 解决方案 > Delphi中的TRESTRequest JSON POST问题

问题描述

我正在尝试使用 TRESTClient (Delphi 10.4/Windows 10) 将 JSON POST 请求发送到 API,但我收到409 冲突,指示 "No input found"。在(Delphi XE6/Windows 10)中使用相同的代码,我得到一个REST 请求失败:Socket Error # 10054 Connection reset by peer。. 使用 WireShark,我可以看到 Delphi XE6 使用 TLS 1.0 发送请求,而 Delphi 10.4 使用 TLS v1.2。API 服务仅接受 TLS v1.2。有没有办法在 Delphi XE6 中使用这些 REST 组件通过 TLS 1.2 传递请求?

我相信我的问题是我使用代码对所有输入进行 JSON 编码:

// Assign JSON
  sl := TStringList.Create;
  sl.Add('locations=[{"address":"Test1","lat":"52.05429","lng":"4.248618"},{"address":"Test2","lat":"52.076892","lng":"4.26975"},{"address":"Test3","lat":"51.669946","lng":"5.61852"},{"address":"Sint-Oedenrode, The Netherlands","lat":"51.589548","lng":"5.432482"}]');

然后使用 将其分配给请求正文RESTRequest.AddBody(sl);,而 API 只期望位置参数的值是 JSON。我更新了代码以将 JSON 分配给字符串,并使用RESTRequest.Params.Items[0].name := 'locations';andRESTRequest.Params.Items[0].Value := s;将字符串添加到请求正文中。

这是我更新的代码:

procedure TMainForm.btn_RouteXL_PostClick(Sender: TObject);
var
  s, sResult, AError: String;
  jsObj: TJSONObject;
  AJSONValue, jsResponse: TJSONValue;
  AParameter: TRESTRequestParameter;
  AStatusCode: Integer;

begin
  //ResetRESTComponentsToDefaults;

  s := '[{"address":"Test1","lat":"52.05429","lng":"4.248618"},{"address":"Test2","lat":"52.076892","lng":"4.26975"},{"address":"Test3","lat":"51.669946","lng":"5.61852"},{"address":"Sint-Oedenrode, The Netherlands","lat":"51.589548","lng":"5.432482"}]';

  RESTClient.BaseURL := 'https://api.routexl.com/tour';
  RESTClient.ContentType := 'ctAPPLICATION_X_WWW_FORM_URLENCODED';
  RESTClient.Authenticator := HTTPBasic_RouteXL;

  RESTRequest.Method := TRESTRequestMethod.rmPOST;

  RESTRequest.Params.AddItem; //Adds a new Parameter Item
  RESTRequest.Params.Items[0].name := 'locations'; //sets the name of the parameter. In this case, since I need to use 'locations=' on the request, the parameter name is locations.
  RESTRequest.Params.Items[0].Value := s; //Adds the value of the parameter, in this case, the JSON data.
  RESTRequest.Params.Items[0].ContentType := ctAPPLICATION_X_WWW_FORM_URLENCODED; //sets the content type.
  RESTRequest.Params.Items[0].Kind := pkGETorPOST; //sets the kind of request that will be executed.

  RESTRequest.Execute;

  try
    memo_ResponseData.Lines.Add('************JSONText*******************');
    memo_ResponseData.Lines.Add(RESTResponse.JSONValue.ToString);
    //Memo1.Lines.Add('JSONValue  :'+RESTResponse.JSONValue.Value);
    memo_ResponseData.Lines.Add('StatusText :'+RESTRequest.Response.StatusText );
    memo_ResponseData.Lines.Add('StatusCode :'+IntToStr(RESTRequest.Response.StatusCode ));
    memo_ResponseData.Lines.Add('ErrorMesage:'+RESTRequest.Response.ErrorMessage);
    memo_ResponseData.Lines.Add('************Content*******************');
    memo_ResponseData.Lines.Add(RESTRequest.Response.Content);
    memo_ResponseData.Lines.Add('************Headers*******************');
    memo_ResponseData.Lines.Add(RESTRequest.Response.Headers.Text);
  except
    on E: Exception do
    begin
      memo_ResponseData.Lines.Add('************Error*******************');
      memo_ResponseData.Lines.Add('Error : ' +E.Message);
      memo_ResponseData.Lines.Add(E.ClassName);
      memo_ResponseData.Lines.Add('************Error*******************');
      memo_ResponseData.Lines.Add('Error : '+RESTResponse.Content);
    end;
  end;

end;

我可以使用键值对使其在 Postman 中工作,方法是将键分配为位置,将值分配为sl屏幕截图中的内容。但我无法将其翻译为 Delphi。

在此处输入图像描述

标签: jsondelphi

解决方案


推荐阅读