是否可以使用 Spring WebClient 在 GET 请求中包含请求正文?

Mir*_*Fan 11 java spring spring-webflux spring-webclient

我知道使用 GET 请求发送正文并不是最好的主意,但我正在尝试使用需要它的现有 API。

使用 POST 发送正文非常简单:

webClient.post()
        .uri("/employees")
        .body(Mono.just(empl), Employee.class)
        .retrieve()
        .bodyToMono(Employee.class);
Run Code Online (Sandbox Code Playgroud)

但它不起作用webClient.get(),因为当该post()方法返回 a时WebClient.RequestBodyUriSpec,该get()方法返回WebClient.RequestHeadersUriSpec<?>,这似乎不允许任何主体定义。

我在这里找到了 Spring RestTemplate 的解决方法:RestTemplate get with body,但没有找到新 WebClient 的解决方法。

Bre*_*t Y 10

虽然其他响应是正确的,您不应使用带有 GET 请求的正文,但当您不拥有或无法更改您正在调用的现有方法时,这没有帮助。

问题是WebClient#get返回 aWebClient.RequestHeadersUriSpec并没有为我们提供设置主体的方法。

WebClient#post返回 a ,WebClient.RequestBodyUriSpec它确实为我们提供了一种设置正文的方法,但会导致我们使用错误的 HTTP 方法,POST 而不是 GET。

值得庆幸的是,我们陷入了这种情况,有WebClient#method一个返回 aWebClient.RequestBodyUriSpec并允许我们设置 HTTP 方法。

webClient.method(HttpMethod.GET)
        .uri("/employees")
        .body(Mono.just(empl), Employee.class)
        .retrieve()
        .bodyToMono(Employee.class);

Run Code Online (Sandbox Code Playgroud)

不过,您可能仍然会在测试库中遇到问题......


Lui*_*ado 1

GET 请求没有主体。HTTP 规范禁止(好吧,不是禁止,但根本不使用)。这里有两种方法:

  • 发个帖子。它就是为此而存在的。
  • 使用查询字符串并传递 URL 该部分中的数据。

当然,您可以附加所需的字段并将有效负载传递给 GET 请求,但在您提供的代码访问它之前,它可能会被忽略,或者更糟的是,被识别为错误并被服务器拒绝。但是,如果您要将数据传递到服务器以对其进行一些处理,那么您需要使用 POST。

摘自 RFC-7231。HTTP 1.1。语义和代码:

GET 请求消息中的有效负载没有定义的语义; 在 GET 请求上发送有效负载正文可能会导致某些现有实现拒绝该请求。

(标记是我的)

其原因主要是 GET 方法必须是幂等的,如果重复,则会为相同的 URL 生成相同的输出。POST 没有这些要求,所以 POST 是你的朋友。

  • 我同意这样的观点,即使用带有 body 的 GET 请求是不好的做法,而且我不会以这种方式设计自己的 API。然而,正如我在原始问题的第一句话中所描述的,我使用的 API 期望使用在正文中定义的查询详细信息的 GET。向同一端点发送 POST 会返回错误。我也不确定幂等性是否是 GET 不能有主体的原因。PUT 也是幂等的,并且通常包含有效负载。 (2认同)