#java #spring-webflux #project-reactor
#java #spring-webflux #проект-реактор
Вопрос:
Я хочу использовать 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)
.
Есть ли способ на самом деле достичь этого?
Ответ №1:
Вы могли бы изменить свой 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
для каждого запроса. Используйте предопределенные WebClient.Builder
компоненты из Spring Boot или повторно используйте один собственный экземпляр.
Комментарии:
1. К сожалению, это, вероятно, будет не
Mono<MultiValueMap<String, String>>
, аMultiValueMap<String, Flux<String>>
, с которым сложно работать.