【问题标题】:Is it possible to include a request body in a GET request using Spring WebClient?是否可以使用 Spring WebClient 在 GET 请求中包含请求正文?
【发布时间】:2021-11-09 19:47:05
【问题描述】:

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

使用 POST 发送正文很简单:

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

但它不适用于webClient.get(),因为虽然post() 方法返回WebClient.RequestBodyUriSpec,但get() 方法返回WebClient.RequestHeadersUriSpec<?>,这似乎不允许任何主体定义。

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

【问题讨论】:

  • ~你不能,因为 HTTP 不支持它——据我所知。~我的立场是正确的——你可以用 GET 发送一个正文;虽然这是一件很奇怪的事情。您是否尝试过使用.method(GET)
  • @BoristheSpider 的方法应该可以正常工作(如果我们发送没有位置标头的CREATED 响应,我们可能会使用相同的解决方法)。但我必须同意鲍里斯的观点,即发送带有 get 的身体 - 虽然不是严格禁止 - 是非常不鼓励而不是最佳实践。
  • 确实有效!非常感谢@BoristheSpider。我怎么没注意到通用的.method()

标签: java spring spring-webflux spring-webclient


【解决方案1】:

GET 请求没有正文。 HTTP 规范禁止(嗯,不禁止,但根本不使用)它。这里有两种方法:

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

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

从 RFC-7231 中提取。 HTTP 1.1。语义和代码:

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

(标记是我的)

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

【讨论】:

  • 我同意将 GET 请求与正文一起使用是不好的做法的观点,我不会以这种方式设计自己的 API。但是,正如我在原始问题的第一句话中所描述的,我使用的 API 需要一个在正文中定义查询详细信息的 GET。向同一端点发送 POST 将返回错误。我也不确定幂等性是否是 GET 不能有主体的原因。 PUT 也是幂等的,通常包含有效负载。
【解决方案2】:

我发现自己处于类似情况,虽然其他响应是正确的,但您不应该使用带有 GET 请求的主体,当您不拥有或无法更改您正在调用的现有方法时,该请求无济于事。

问题是WebClient#get返回一个WebClient.RequestHeadersUriSpec,它没有为我们提供设置正文的方法。 1

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

感谢我们陷入这种情况,WebClient#method 返回一个 WebClient.RequestBodyUriSpec 并允许我们设置 HTTP 方法。

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

You may still run into issues in your testing libraries though...

【讨论】:

    猜你喜欢
    • 2022-01-25
    • 2021-11-03
    • 1970-01-01
    • 2021-06-28
    • 2022-08-15
    • 2020-09-20
    • 1970-01-01
    • 2022-01-16
    • 2013-06-29
    相关资源
    最近更新 更多