Spring 5 WebClient 仅在 .exchange() 之后使用 .block() 时进行 Http 调用
Spring 5 WebClient only making Http call when using .block() after .exchange()
此调用按预期工作并使 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();
}
}
内部配置class:
@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);
};
}
在上面的示例中,我们看到记录了 URL、属性和 Headers,并且 Http 调用已完全成功。但是,仅删除 block() 调用会导致没有调用,也没有日志:
// No call made
final WebClient.ResponseSpec responseSpec = webClient.post()
.uri(new URI(url + "/tasks/executions"))
.body(BodyInserters.fromMultipartData(requestParms))
.exchange();
那是因为它是非阻塞的...
来自 Spring Docs:
Simply put, WebClient is an interface representing the main entry
point for performing web requests.
It has been created as a part of the Spring Web Reactive module and
will be replacing the classic RestTemplate in these scenarios. The new
client is a reactive, non-blocking solution that works over the
HTTP/1.1 protocol.
这是一个使用 Reactive Streams concept through the Project Reactor 实现的实现
此调用按预期工作并使 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();
}
}
内部配置class:
@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);
};
}
在上面的示例中,我们看到记录了 URL、属性和 Headers,并且 Http 调用已完全成功。但是,仅删除 block() 调用会导致没有调用,也没有日志:
// No call made
final WebClient.ResponseSpec responseSpec = webClient.post()
.uri(new URI(url + "/tasks/executions"))
.body(BodyInserters.fromMultipartData(requestParms))
.exchange();
那是因为它是非阻塞的...
来自 Spring Docs:
Simply put, WebClient is an interface representing the main entry point for performing web requests.
It has been created as a part of the Spring Web Reactive module and will be replacing the classic RestTemplate in these scenarios. The new client is a reactive, non-blocking solution that works over the HTTP/1.1 protocol.
这是一个使用 Reactive Streams concept through the Project Reactor 实现的实现