如何使用请求正文调用 API 端点?
Posted
技术标签:
【中文标题】如何使用请求正文调用 API 端点?【英文标题】:How to call an API endpoint with a request body? 【发布时间】:2022-01-13 03:46:25 【问题描述】:我在 Spring 中构建了一个 REST API,目前运行良好。我现在想在我的请求中添加一个带有数据的正文。我的 REST API 端点等待请求中的正文数据,如下所示。
@RestController
public class TestController
@GetMapping("/test")
public String Test(@RequestBody(required=true) String fullName)
return "Hello " + fullName;
我尝试通过命令行调用端点,如下所示。
curl -X GET -H "Content-type: application/json" -d "John Doe" "http://localhost:8080/test"
这会产生以下结果,并证明 REST API 工作正常。
Hello John Doe
无论如何我都无法在 Delphi 中完成。
procedure TForm1.Button1Click(Sender: TObject);
var
RESTClient : TRESTClient;
RESTRequest : TRESTRequest;
RESTResponse : TRESTResponse;
begin
RESTClient := TRESTClient.Create(nil);
RESTClient.BaseURL := 'http://localhost:8080/test';
RESTResponse := TRESTResponse.Create(nil);
RESTRequest := TRESTRequest.Create(nil);
RESTRequest.Client := RESTClient;
RESTRequest.Response := RESTResponse;
RESTRequest.Execute;
if RESTResponse.Status.Success then
begin
ShowMessage(RESTResponse.Content);
end;
end;
有谁知道我如何做到这一点?我非常感谢任何形式的帮助,纯粹的!
我尝试以多种不同的方式调用端点,如下所示。
// see above...
RESTRequest.ClearBody;
RESTRequest.Params.AddHeader('Content-Type', 'application/json');
RESTRequest.Body.Add('"fullname": "John Doe"');
RESTRequest.Execute;
很遗憾,这会导致以下错误。
DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Invalid mime type "application%2Fjson": does not contain '/']
【问题讨论】:
【参考方案1】:我的幼稚做法是:
RESTRequest.ClearBody;
RESTRequest.AddBody('John Doe');
RESTRequest.Execute;
这将生成一个普通的字符串主体。如果您确实需要 JSON 正文,您可以编写
RESTRequest.AddBody('"fullname": "John Doe"', TRESTContentType.ctAPPLICATION_JSON);
但由于我对 Spring 不熟悉,我不确定它是否适合这里。
更新:在您将服务器更改为接受 JSON 对象后,第二种方法似乎更好。在这种情况下,您甚至可以使用类似的 Delphi 类。
type
TPerson = class
private
FFirstname: string;
FLastname: string;
public
property Firstname: string read FFirstname write FFirstname;
property Lastname: string read FLastname write FLastname;
end;
person := TPerson.Create;
try
person.Firstname := 'John';
person.Lastname := 'Doe';
RESTRequest.AddBody<TPerson>(person);
finally
person.Free;
end;
【讨论】:
您的第一种方法会导致以下错误:Resolved [org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public java.lang.String com.example.restservice.KernpruefungController.AAG(java.lang.String)]
。我无法尝试您的第二种方法,因为 TRESTContentType.ctAPPLICATION_JSON
似乎是一个未定义的标识符。我在这里缺少任何导入吗?
我已经弄清楚我错过了哪个单元。无论如何,它会遇到与另一个相同的错误。
我更新了我的答案,但我仍然不确定。不幸的是,如果不访问 REST 服务器,我无法对其进行测试。
你已经帮了我很多了——我已经弄明白了为什么它不起作用(见我的回答)。也许你知道为什么。顺便说一句,-H
定义了通常包含有关请求的信息的标头,-d
是包含随请求传递的所有数据的正文部分。
我也更喜欢您的初始答案,因为它帮助我找到了解决方案,所以您是否可以将答案更改为初始答案?【参考方案2】:
我已将方法从 GET 更改为 POST,因为我只会向 REST API 发出 POST 请求。不幸的是,这解决了我最初的问题,即使我不知道确切的原因......无论如何这里是一个快速演练。
首先,您必须创建一个类,Spring 稍后会使用该类使用 JSON 中的给定数据创建一个实例。请注意,此步骤是可选的,但非常推荐。
public class Person
private String firstname;
private String lastname;
public Person (String firstname, String lastname)
this.firstname = firstname;
this.lastname = lastname;
public String getFirstname()
return firstname;
public String getLastname()
return lastname;
更新后的端点如下所示。
@PostMapping(
value = "/test",
consumes = MediaType.APPLICATION_JSON_VALUE // awaits JSON
)
public String Test(@RequestBody Person person)
return person.getFirstname()); // will return John
参考@Uwe Raabe's 的答案,我正在调用 Delphi 中的 REST API 端点,如下所示。请注意,我在正文数据周围添加了典型的 JSON 语法,这是必要的,因为 Spring 无法在没有它的情况下创建数据类。
// ...
RESTRequest.ClearBody;
RESTRequest.AddBody('"firstname": "John", "lastname": "Doe"', ctAPPLICATION_JSON);
RESTRequest.Execute;
【讨论】:
以上是关于如何使用请求正文调用 API 端点?的主要内容,如果未能解决你的问题,请参考以下文章
如何在访问原始请求正文的同时为 Web API 帮助页面生成正文参数/示例请求
如何使用 Scala 在具有请求正文的 REST API 上执行 GET 请求?
如何使用标头、有效负载和正文制作 httpclient 获取请求?角度 API
使用 http 端点访问 lambda 中的 HTTP 请求(标头、查询字符串、cookie、正文)对象
异步任务HttpPost请求DoInbackground调用web api Android Studio Java,如何添加正文字符串数组?