我正在为一个客户的集成项目工作,该客户需要使用Delphi 10.2 Tokyo服务程序中的eParcel REST API创建AusPost发货。
这是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;
以及它使用的常量(请注意,帐户和API值来自参考API,可能实际上不起作用)。
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方法是创建发货和获取发货。
这是我的Get Shipments Delphi代码的样子(不用担心AJSONValue
响应。仍在努力最终将完成什么工作):
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": "[email protected]",
"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
}
}
我的创建货件几乎相同:
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": "[email protected]"'+
' },'+
' "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中设置了Create Shipment POST,而Raw Body是相同的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错误。如果我在使用Postman时未在请求中包含正文,则会收到以下响应:
{
"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的请求中包含主体,则会收到相同的404错误。有谁知道我可以尝试使用我的代码的其他REST API?还是有人成功使用了Delphi的AusPost eParcel API,即使它是通过Indy完成的呢?
找到了问题,即使我无法解释。一旦删除了Content-Type参数代码,post方法就可以正常工作。
// AParameter := RESTRequest.Params.AddItem;
// AParameter.ContentType := ctAPPLICATION_JSON;
// AParameter.name := 'Content-Type';
// AParameter.Value := 'application/json';
// AParameter.Kind := TRESTRequestParameterKind.pkHTTPHEADER;
不知何故,包括在请求中只是塞满了东西。没有任何原因的解释,但这可能只是那些Delphi REST库的怪癖之一。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句