在我们的项目中,我们决定尝试使用spring webclient来请求外部API。但是我们不需要React式方法,所以我们决定在同步模式下使用webclient。我们使用的外部API需要授权,然后在请求的Authorization头中替换一个token。我们编写了一个拦截器,每当调用外部API时,被触发并使用API令牌补充请求。但我们遇到了一个问题,即同一个Web客户端无法在同步模式下的拦截器中使用,因为它给出了一个错误:block()/blockfirst()/blocklast() are blocking, which is not supported in thread parallel-1
在GitHub上发现一个问题:https://github.com/spring-projects/spring-framework/issues/22919但我们没有收到一个明确的理解如何解决这个问题。请告诉我有什么选择来解决这个问题?我的代码示例(这只是一个最小的例子,实际代码更复杂):
@Bean
public WebClient webClient() {
.....
return WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(httpClient))
.baseUrl(properties.getBaseUrl())
.filter(retryRequest())
.filter(WebclientUtils.exchangeFilterLogRequest())
.filter(authExchangeFilterFunction())
.filter(httpStatusErrorHandling())
.filter(WebclientUtils.exchangeFilterLogResponse())
.build();
}
private ExchangeFilterFunction authExchangeFilterFunction() {
return (request, next) -> {
WebClient webClient = WebClient.builder()
.baseUrl(properties.getBaseUrl())
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.filter(ExchangeFilterFunctions.basicAuthentication(
properties.getAuth().getBasic().getUsername(),
properties.getAuth().getBasic().getPassword()
)
)
.filter(WebclientUtils.exchangeFilterLogRequest())
.filter(WebclientUtils.exchangeFilterLogResponse())
.build();
//generate form data
//.......
String token = webClient.post()
.uri("/oauth/token")
.body(BodyInserters.fromFormData(formData))
.retrieve()
.bodyToMono(String.class)
.block();
next.exchange(ClientRequest.from(request)
.header(HttpHeaders.AUTHORIZATION, token)
.build()))
}
}
字符串
1条答案
按热度按时间5cg8jx4n1#
在这种情况下,你不需要使用block,这与使用不同的操作符链接操作有关,这里是
flatMap
。此外,重用WebClient
示例并避免为每个调用分配这些示例是一个好主意。字符串