others - delphi REST get不能与AusPost eParcel API一起使用POST

下面是我的类的Constructor


constructor TAusPostRESTServices.Create;


begin


 // Create the REST objects



 HTTPBasicAuthenticator := THTTPBasicAuthenticator.Create(API_KEY, API_PASSWORD);


 RESTClient := TRESTClient.Create(BASE_URL);


 RESTResponse := TRESTResponse.Create(nil);


 RESTRequest := TRESTRequest.Create(nil);



 // Set the initial properties



 RESTClient.Params.Clear;


 RESTClient.HandleRedirects := true;


 RESTClient.Authenticator := HTTPBasicAuthenticator;


 RESTClient.RaiseExceptionOn500 := false;



 RESTRequest.Client := RESTClient;


 RESTRequest.Response := RESTResponse;


 RESTRequest.SynchronizedEvents := false;


end;




const


 BASE_URL = 'https://digitalapi.auspost.com.au/test';


 ACCOUNT = '0000123456';


 API_KEY = '601a4032-6dbd-46aa-9c6c-8c6dacca5e61';


 API_PASSWORD = 'password';



Uses子句至少有以下这些:


REST.Client, REST.Authenticator.Basic, IPPeerClient, JSON, REST.Types



我正在尝试使用的eParcel API方法是创建发货获取货件


function TAusPostRESTServices.GetShipments(var AError: String): Boolean;


var


 AStatusCode: Integer;


 AJSONString: String;


 AJSONValue: TJSonValue;


 AParameter: TRESTRequestParameter;


begin


 // Set the request header info



 RESTRequest.Method := TRESTRequestMethod.rmGET;


 RESTRequest.Resource := '/shipping/v1/shipments';


 RESTRequest.Accept := 'application/json';



 AParameter := RESTRequest.Params.AddItem;


 AParameter.ContentType := ctAPPLICATION_JSON;


 AParameter.name := 'Content-Type';


 AParameter.Value := 'application/json';


 AParameter.Kind := TRESTRequestParameterKind.pkHTTPHEADER;



 RESTRequest.Params.AddHeader('account-number', ACCOUNT);



 try


 try


 RESTRequest.Execute;


 except on E: Exception do


 ;


 end;



 // If the StatusCode is 200, then the REST method worked



 AStatusCode := RESTRequest.Response.StatusCode;



 if AStatusCode <> 200 then


 AError := RESTRequest.Response.Content


 else


 begin


 AJSONValue := TJSonObject.ParseJSONValue(RESTRequest.Response.Content);



 AJSONValue.Free;



 AError := '';


 end;


 finally


 Result := (AError = '');


 end;


end;



这可以正常工作,并从AusPost API文档中包含的例子JSON,我使用Postman创建的演示。


{


"shipments": [


 {


"shipment_id":"T7sK0EA9HGcAAAFufLYgUxkK",


"shipment_reference":"My second shipment ref",


"shipment_creation_date":"2019-10-30T06:42:42+11:00",


"customer_reference_1":"cb1234",


"customer_reference_2":"cb2345",


"sender_references": [


"cb1234",


"cb2345"


 ],


"from": {


"type":"MERCHANT_LOCATION",


"lines": [


"111 Bourke St"


 ],


"suburb":"Melbourne",


"postcode":"3000",


"state":"VIC",


"apcn":"2468013579",


"name":"Carl Block",


"country":"AU"


 },


"to": {


"type":"STANDARD_ADDRESS",


"lines": [


"PO Box 123"


 ],


"suburb":"Rye",


"postcode":"3941",


"state":"VIC",


"apcn":"1234567890",


"name":"Blocked Carl",


"business_name":"In debt",


"country":"AU",


"email":"carl@gmai.co",


"phone":"0356567567",


"delivery_instructions":"please leave behind shed"


 },


"items": [


 {


"weight": 1,


"height": 10,


"length": 10,


"width": 10,


"contains_dangerous_goods": false,


"authority_to_leave": true,


"safe_drop_enabled": true,


"allow_partial_delivery": false,


"item_id":"3mQK0EA9CksAAAFui7YgUxkK",


"item_reference":"blocked",


"tracking_details": {


"article_id":"111JD538925401000930800",


"consignment_id":"111JD5389254"


 },


"product_id":"7E55",


"item_summary": {


"total_cost": 11.48,


"total_cost_ex_gst": 11.48,


"total_gst": 0,


"status":"Created"


 },


"item_contents": [],


"label": {


"status":"Pending",


"errors": []


 },


"postage_details": {


"price": {


"calculated_price": 11.48,


"calculated_price_ex_gst": 11.48,


"calculated_gst": 0


 }


 }


 },


 {


"weight": 2.123,


"height": 10,


"length": 100.1,


"width": 10,


"contains_dangerous_goods": false,


"authority_to_leave": true,


"safe_drop_enabled": true,


"allow_partial_delivery": false,


"item_id":"9cgK0EA9smIAAAFufrYgUxkK",


"item_reference":"blocked",


"tracking_details": {


"article_id":"111JD538925403000930804",


"consignment_id":"111JD5389254"


 },


"product_id":"7E55",


"item_summary": {


"total_cost": 23.34,


"total_cost_ex_gst": 23.34,


"total_gst": 0,


"status":"Created"


 },


"item_contents": [],


"label": {


"status":"Pending",


"errors": []


 },


"postage_details": {


"price": {


"calculated_price": 23.34,


"calculated_price_ex_gst": 23.34,


"calculated_gst": 0


 }


 }


 },


 {


"weight": 1,


"height": 10,


"length": 10,


"width": 10,


"contains_dangerous_goods": false,


"authority_to_leave": true,


"safe_drop_enabled": true,


"allow_partial_delivery": false,


"item_id":"_hEK0EA9zIIAAAFuirYgUxkK",


"item_reference":"blocked",


"tracking_details": {


"article_id":"111JD538925402000930807",


"consignment_id":"111JD5389254"


 },


"product_id":"7E55",


"item_summary": {


"total_cost": 11.48,


"total_cost_ex_gst": 11.48,


"total_gst": 0,


"status":"Created"


 },


"item_contents": [],


"label": {


"status":"Pending",


"errors": []


 },


"postage_details": {


"price": {


"calculated_price": 11.48,


"calculated_price_ex_gst": 11.48,


"calculated_gst": 0


 }


 }


 }


 ],


"options": {},


"shipment_summary": {


"total_cost": 47.41,


"total_cost_ex_gst": 43.1,


"fuel_surcharge": 1.11,


"total_gst": 4.31,


"status":"Created",


"tracking_summary": {


"Created": 3


 },


"number_of_items": 3


 },


"movement_type":"DESPATCH",


"charge_to_account":"1001746337"


 }


 ],


"pagination": {


"total_number_of_records": 1,


"number_of_records_per_page": 1000,


"current_page_number": 1


 }


}



我的创建Shipment:


function TAusPostRESTServices.CreateShipment(var AError: String): Boolean;


var


 AStatusCode: Integer;


 AJSONString: String;


 AJSONValue: TJSonValue;


 AParameter: TRESTRequestParameter;


begin


 // Set the request header info



 RESTRequest.Method := TRESTRequestMethod.rmPOST;


 RESTRequest.Resource := '/shipping/v1/shipments';


 RESTRequest.Accept := 'application/json';



 AParameter := RESTRequest.Params.AddItem;


 AParameter.ContentType := ctAPPLICATION_JSON;


 AParameter.name := 'Content-Type';


 AParameter.Value := 'application/json';


 AParameter.Kind := TRESTRequestParameterKind.pkHTTPHEADER;



 RESTRequest.Params.AddHeader('account-number', ACCOUNT);



 try


 AJSONString := '{'+


 '"shipments": ['+


 ' {'+


 '"shipment_reference":"139301",'+


 '"customer_reference_1":"1",'+


 '"from": {'+


 '"name":"MERCHANT_LOCATION",'+


 '"lines": ['+


 '"111 Bourke St"'+


 ' ],'+


 '"suburb":"MELBOURNE",'+


 '"postcode":"3000",'+


 '"state":"VIC"'+


 ' },'+


 '"to": {'+


 '"name":"STANDARD_ADDRESS",'+


 '"lines": ['+


 '"PO Box 123"'+


 ' ],'+


 '"suburb":"Rye",'+


 '"state":"VIC",'+


 '"postcode":"3941",'+


 '"delivery_instructions":"please leave behind shed",'+


 '"email":"carl@gmai.co"'+


 ' },'+


 '"items": ['+


 ' {'+


 '"width": 10,'+


 '"height": 10,'+


 '"length": 10,'+


 '"weight": 0.19,'+


 '"product_id":"7E55",'+


 '"authority_to_leave": true'+


 ' }'+


 ' ]'+


 ' }'+


 ' ]'+


 '}';



 RESTRequest.Body.Add(AJSONString, ctAPPLICATION_JSON);



 try


 RESTRequest.Execute;


 except on E: Exception do


 ;


 end;



 // If the StatusCode is 200, then the REST method worked



 AStatusCode := RESTRequest.Response.StatusCode;



 if AStatusCode <> 200 then


 AError := RESTRequest.Response.Content


 else


 begin


 AJSONValue := TJSonObject.ParseJSONValue(RESTRequest.Response.Content);



 AJSONValue.Free;



 AError := '';


 end;


 finally


 Result := (AError = '');


 end;


end;



运行此命令时,状态代码为404,内容文本为,


{


"code":"404",


"name":"Not Found",


"message":"Invalid HTTP method POST or request path /shipments. Please refer to the Developer Centre reference at https://developers.auspost.com.au/apis/shipping-and-tracking/reference for correct usage."


}



但是如果我在Postman中POST了Shipment,原始主体是相同的JSON字符串,那么我得到响应:


{


"shipments": [


 {


"shipment_id":"QdkK0EA99JoAAAFuba0gUzkF",


"shipment_reference":"139301",


"shipment_creation_date":"2019-11-05T11:45:03+11:00",


"items": [


 {


"weight": 0.190,


"authority_to_leave": true,


"safe_drop_enabled": true,


"allow_partial_delivery": true,


"item_id":"kwgK0EA9Es8AAAFubq0gUzkF",


"tracking_details": {


"article_id":"111JD539319101000931501",


"consignment_id":"111JD5393191"


 },


"product_id":"7E55",


"item_summary": {


"total_cost": 17.14,


"total_cost_ex_gst": 17.14,


"total_gst": 0.00,


"status":"Created"


 },


"item_contents": []


 }


 ],


"options": {},


"shipment_summary": {


"total_cost": 17.55,


"total_cost_ex_gst": 15.95,


"fuel_surcharge": 0.41,


"total_gst": 1.60,


"status":"Created",


"tracking_summary": {


"Created": 1


 },


"number_of_items": 1


 },


"movement_type":"DESPATCH",


"charge_to_account":"1001746337"


 }


 ]


}



我不明白的是,为什么Delphi会给我这个404错误,


{


"errors": [


 {


"code":"400",


"name":"INVALID_PAYLOAD",


"message":"Unable to deserialize payload. Please ensure that the payload is valid JSON. Please note that when assigned, boolean fields can only accept 'true' or 'false' as values."


 }


 ]


}



但是,如果我没有在Delphi的请求中包含body,则会出现404错误。

时间:

删除Content-Type参数代码后,post方法工作正常。


// AParameter := RESTRequest.Params.AddItem;


// AParameter.ContentType := ctAPPLICATION_JSON;


// AParameter.name := 'Content-Type';


// AParameter.Value := 'application/json';


// AParameter.Kind := TRESTRequestParameterKind.pkHTTPHEADER;



...