如何设置WebClient的基本url和查询参数?

sin*_*mos 6 spring spring-webflux

在我的服务中,我必须从一些带有参数的不同网址获取响应。

  1. 从http://a.com:8080/path1?param1=v1获取
  2. 从http://b.com:8080/path2?param2=v2获取
  3. 从http://c.com:8080/path3?param3=v3获取

我正在使用 WebClient 来完成以下工作。

public class WebClientTest {
    private WebClient webClient = WebClient.builder().build();

    @Test
    public void webClientTest() {
        Mono<String> a = webClient.get()
            .uri(uriBuilder -> uriBuilder.scheme("http").host("a.com").port(8080).path("/path1")
                    .queryParam("param1", "v1")
                    .build())
            .retrieve()
            .bodyToMono(String.class);

        Mono<String> b = webClient.get()
            .uri(uriBuilder -> uriBuilder.scheme("http").host("b.com").port(8080).path("/path2")
                    .queryParam("param2", "v2")
                    .build())
            .retrieve()
            .bodyToMono(String.class);

        Mono<String> c = webClient.get()
            .uri(uriBuilder -> uriBuilder.scheme("http").host("c.com").port(8080).path("/path3")
                    .queryParam("param3", "v3")
                    .build())
            .retrieve()
            .bodyToMono(String.class);

        //zip the result
    }
}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,我必须一次又一次地分别设置方案、主机、端口。
所以我的问题是:
1.我是否以正确的方式使用WebClient?
2. 是否可以在一个方法中同时设置scheme、host、port?我知道这是webClient.get().uri("http://a.com:8080/path1?param1=v1").retrieve()可行的,但我期待的是:

    webClient.get()
            .uri(uriBuilder -> uriBuilder/*.url("http://a.com:8080/path1")*/
                    .queryParam("param1", "v1")
                    .build())
            .retrieve()
            .bodyToMono(String.class);
Run Code Online (Sandbox Code Playgroud)

Bri*_*zel 22

从 Spring Framework 5.2 开始,有一个额外的方法可以帮助您解决特定情况:

Mono<String> response = this.webClient
    .get()
    .uri("http://a.com:8080/path1", uri -> uri.queryParam("param1", "v1").build())
    .retrieve()
    .bodyToMono(String.class);
Run Code Online (Sandbox Code Playgroud)

WebClient作为一般规则,我不建议为每个主机创建一个。这实际上取决于您的用例。在这里,您的客户端可能会向许多主机发送请求,并且创建许多 HTTP 客户端在这里可能有点浪费。

  • 这对我有用。对于任何尝试使用 `.uri(uriBuilder -&gt; uriBuilder.path().queryParam( ... ) )` 的人来说,如果在 WebClientConfiguration 中配置了带有 baseUrl 的 Bean,它可能不起作用。该 baseUrl 将添加到您的请求之前。 (2认同)