有没有办法将Flux作为表单数据提供给WebClient的正文?

问题描述 投票:0回答:1

我想使用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)

有没有办法真正实现这一目标?

java spring-webflux project-reactor
1个回答
0
投票

您可以更改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或重用自己的一个实例。

© www.soinside.com 2019 - 2024. All rights reserved.