如何使用请求正文调用 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,如何添加正文字符串数组?