我想使用WebClient访问某些受限资源,因此需要提供登录名和密码并将其编码为表单数据。它的效果很好
private Mono<MyDataType> getMyDataType() {
return WebClient.builder().build().post()
.uri(MY_URI)
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.body(BodyInserters.fromFormData(getFormData()))
.exchange()
.flatMap(clientResponse -> clientResponse.bodyToMono(MyDataType.class));
}
private MultiValueMap<String, String> getFormData() {
MultiValueMap<String, String> credentials = new LinkedMultiValueMap<>();
credentials.add("login", readLoginStringFromDiskAsString);
credentials.add("password", readPasswordStringFromDiskAsString);
}
然而,正如你所看到的,我的read*
函数是阻塞 - 简单的Files.readAllBytes
,就像你在任何其他应用程序中所做的那样。我想将这个读取从磁盘转换为更异步的东西,比如使用DataBufferUtils或类似的东西。问题是,Spring只提供了fromFormData
的一个实现 - fromFormData(MultiValueMap<String, String> formData)
。
有没有办法真正实现这一目标?
您可以更改getFormData
方法以返回Mono<MultiValueMap<String, String>>
并将其结果平面映射到异步访问凭据
private Mono<MultiValueMap<String, String>> getFormDataNonBlocking() {
//asynchronous nonblocking reading of the credentials
}
private Mono<MyDataType> getMyDataType() {
return getFormDataNonBlocking()
.flatMap(credentials -> WebClient.builder()
.build()
.post()
.uri(MY_URI)
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.body(BodyInserters.fromFormData(credentials))
.exchange()
.flatMap(clientResponse -> clientResponse.bodyToMono(MyDataType.class)));
}
有一个说明。您不应为每个请求创建新的WebClient
。使用Spring Boot中预定义的WebClient.Builder
bean或重用自己的一个实例。