Spring 5 WebClient 仅在 .exchange() 之后使用 .block() 时进行 Http 调用

Joh*_*Doe 2 spring spring-webflux

此调用按预期工作并使 POST 成功:

public class MyService implements IMyService {

private final WebClient webClient;
private final String url;

MyService(@Qualifier("web-client") WebClient webClient,
                      String url) {
    this.webClient = webClient;
    this.url = url;
}

@SneakyThrows
@Override
public void execute(Long jobId) {
    MultiValueMap<String, String> requestParms = new LinkedMultiValueMap<>();
    requestParms.add("arguments", "--batchJobId=" + jobId.toString());
    HttpEntity<MultiValueMap<String, String>> requestEntity =
        new HttpEntity<>(requestParms, null);

    final WebClient.ResponseSpec responseSpec = webClient.post()
        .uri(new URI(url + "/tasks/executions"))
        .body(BodyInserters.fromMultipartData(requestParms))
        .exchange()
        .block();
}
}
Run Code Online (Sandbox Code Playgroud)

配置类内部:

@Bean
@Qualifier("web-client")
public WebClient getWebClient() {
    return WebClient.builder()
        .filter(basicAuthentication("user", "pass"))
        .filter(printLnFilter())
        .build();
}

private ExchangeFilterFunction printLnFilter() {
    return (request, next) -> {
        System.out.println("\n\n" + request.method().toString().toUpperCase() + ":\n\nURL:"
            + request.url().toString() + ":\n\nHeaders:" + request.headers().toString() + "\n\nAttributes:"
            + request.attributes() + "\n\n");

        return next.exchange(request);
    };
}
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,我们看到记录了 URL、属性和标头,并且 Http 调用完全成功。然而,仅仅删除 block() 调用就会导致没有任何调用,也没有日志:

 // No call made
 final WebClient.ResponseSpec responseSpec = webClient.post()
            .uri(new URI(url + "/tasks/executions"))
            .body(BodyInserters.fromMultipartData(requestParms))
            .exchange();
Run Code Online (Sandbox Code Playgroud)

Uli*_*ses 5

那是因为它是非阻塞的......

来自 Spring文档

简单地说,WebClient 是一个代表执行 Web 请求的主要入口点的接口。

它是作为 Spring Web Reactive 模块的一部分创建的,并将在这些场景中取代经典的 RestTemplate。新客户端是一种反应式、非阻塞解决方案,通过 HTTP/1.1 协议运行。

这是通过Project Reactor实现使用Reactive Streams概念的实现