将C++ API Post请求转换为 Delphi 代码

k7fdbhmy  于 2022-11-29  发布在  其他
关注(0)|答案(1)|浏览(134)

我正在用 Delphi 编程,我很难将C++ API POST请求转换成Delphi。我试过使用Indy,就像我以前使用过的API一样,但是这个似乎不适合我。有人能帮我吗?

需要转换的C++代码:

CURL *hnd = curl_easy_init();

curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(hnd, CURLOPT_URL, "https://sandbox.checkbook.io/v3/check/digital");

struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "accept: application/json");
headers = curl_slist_append(headers, "content-type: application/json");
headers = curl_slist_append(headers, "Authorization: xxxxxxxxxxxxxxxx:xxxxxxxxxxxxxxxxx");
curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, headers);

curl_easy_setopt(hnd, CURLOPT_POSTFIELDS, "{\"recipient\":\"testing@checkbook.io\",\"name\":\"Widgets Inc.\",\"amount\":5,\"description\":\"Test Payment\"}");

CURLcode ret = curl_easy_perform(hnd);

我拥有的 Delphi 代码:

unit API_InvoiceCloud;

interface

uses
  DB, SysUtils,  System.Classes, System.JSON, IdSSLOpenSSL, VCL.Dialogs,
  IdHTTP, XML.XMLIntf, xml.xmlDom, xml.XMLDoc, IDCoder, IDCoderMIME,
  IdBaseComponent, IdException{, IdZLibCompressorBase{, IdCompressorZLib{,Rest.Client};

procedure CreateDigitalPayment_CheckBookAPI(mRecipientEmailAddress,
                                      mRecipientName : String;
                                      mPaymentAmount : Double;
                                      mPaymentNumber,
                                      mPaymentDescription : String);

implementation

var
  { INDY COMPONENT TO CONNECT TO API SERVER; MAKES CONNECTION }
  IDHTTP1 : TidHttp;
  { SSL Connection }
  SSL : TIdSSLIOHandlerSocketOpenSSL;
  { Request and Response vars }
  JsonRequest, InJson : String;
  JsonToSend : TStringStream;    //object to store json text and pass API
  JObj : TJSONObject;
Const
  { Constant variables holding the APIKEY+APISECRET and BASEURL }
  nBASEURL = 'https://sandbox.checkbook.io/v3/check/digital';
  nAPIKEY = 'xxxxxxxxx:xxxxxxxx';

procedure CreateDigitalPayment_CheckBookAPI(mRecipientEmailAddress,
                                            mRecipientName : String;
                                            mPaymentAmount : Double;
                                            mPaymentNumber,
                                            mPaymentDescription : String);
var
  { Response into String }
  SinglePartyResponse : String;
  ResponseCode : String;  
  { -----------Testing---------- }
  //lParamList: TStringList;
  nBASEURL : String;
  RequestBody : TStream;
  ResponseBody : String;
begin
  
  { JSON body with request string }
  JsonRequest := '{"recipient":"' + mRecipientEmailAddress
                + '","name":"' + mRecipientName
                + '","amount":' + FloatToStr(mPaymentAmount)
                + ',"number":"' + mPaymentNumber
                + '","description":"' + mPaymentDescription + '"}';
  
  try

    try
      { Create connection instance }
      IDHTTP1 := TidHttp.Create;

      { SSL Configuration }
      SSL := TIdSSLIOHandlerSocketOpenSSL.Create;
      SSL.SSLOptions.SSLVersions := [sslvTLSv1_1, sslvTLSv1_2];
      IDHTTP1.IOHandler := SSL;

      { Headers/Params }
      IDHTTP1.Request.Clear;
      IDHTTP1.Request.CustomHeaders.FoldLines := False;
      IDHTTP1.Request.Accept := 'application/json';
      IDHTTP1.Request.ContentType := 'application/json';
      IDHTTP1.Request.CustomHeaders.Values['Authorization'] := nAPIKEY;
      
      { Saving JSON text to TStringStream Object }
      JsonToSend := TStringStream.Create(JsonRequest, TEncoding.UTF8);
      //JsonToSend := TStringStream.Create(JsonRequest, TEncoding.ASCII);

      { Making POST Request using INDYs TidHTTP component; Params are: URL, JsonStringObj - saving into variable }
      SinglePartyResponse := IDHTTP1.Post(nBASEURL, JsonToSend);
      
      ShowMessage(IDHTTP1.ResponseCode.ToString);

    except
      on E : Exception do
        { Display error message if cannot do API CALL }
        begin
          ShowMessage(E.ClassName+' error raised, with message : "' + E.Message + '".');
          Abort;
        end
    end;

  finally
    { Free objects from memory }
    IDHTTP1.Free;
    SSL.Free;
    JsonToSend.Free;
  end;
  
end;

end.

当我尝试发出POST请求时,我得到了一个400 Bad Request错误。我不确定我在这里做错了什么。

wr98u20j

wr98u20j1#

找到了解决方案。谢谢你的建议!
400错误请求错误是由于“无效的授权头”
我的解决方案:

1.进入RestDebugger中内置的Embarcadero,并通过设置BASEURLCONTENT-TYPEAUTHORIZATION(参数中的APIKey)和CustomBody使其在其中工作。
**2.**单击“复制组件”按钮并将RESTClientRESTRequestRESTResponse粘贴到空表单上。
**3.**构建JSON字符串并将其作为参数传递给RESTRequest.AddBody,然后执行。(代码如下)

RESTRequest.AddBody(JsonStringRequest, ctAPPLICATION_JSON);
    RESTRequest.Execute();
    RESTResponse := RESTRequest.Response;

有更好的方法来做到这一点,但这对我很有效。

相关问题