如何在 WebClient.exchangeToMono Spring 5.3 中将 ClientResponse 主体作为 DataBuffer 获取?

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

在弃用

WebClient.exchange
方法之前,我曾经将 ClientResponse 主体作为
Flux<DataBuffer>
并对其进行操作。

在 Spring 5.3 中,

exchange()
方法已被弃用,我想按照建议更改实现:

@deprecated since 5.3 due to the possibility to leak memory and/or 连接;请, 使用{@link #exchangeToMono(Function)},{@link #exchangeToFlux(Function)}; 也考虑使用 {@link #retrieve()} ...

试图在传递给

exchangeToMono
的lambda中做同样的调用,但是
clientResponse.bodyToFlux(DataBuffer::class.java)
总是返回一个空的通量;其他实验(即让身体成为单弦)也无济于事。

在 Spring 5.3 中获取 ClientResponse 主体的标准方法是什么?

我正在寻找一个低级的主体表示:比如“数据缓冲区”、“字节数组”或“输入流”;避免任何类型的解析/反序列化。

春节前5.3:

webClient
    .method(GET)
    .uri("http://somewhere.com")
    .exchange()
    .flatMap { clientResponse ->
       val bodyRaw: Flux<DataBuffer> = clientResponse.bodyToFlux(DataBuffer::class.java) 
       // ^ body as expected
           
       // other operations
    }

春后5.3

webClient
    .method(GET)
    .uri("http://somewhere.com")
    .exchangeToMono { clientResponse ->
       val bodyRaw: Flux<DataBuffer> = clientResponse.bodyToFlux(DataBuffer::class.java)
       // ^ always empty flux
           
       // other operations
    }
spring-webflux httpresponse spring-webclient
2个回答
2
投票

新的

exchangeToMono
exchangeToFlux
方法期望主体在回调中被解码。查看此GitHub问题了解详情。

看你的例子,也许你可以使用

retrieve
,这是更安全的选择,用
bodyToFlux

webClient
        .method(GET)
        .uri("http://somewhere.com")
        .retrieve()
        .bodyToFlux(DataBuffer.class)

toEntityFlux
如果您需要访问标题和状态等响应详细信息

webClient
        .method(GET)
        .uri("http://somewhere.com")
        .retrieve()
        .toEntityFlux(DataBuffer.class)

处理错误

Option 1.使用

onErrorResume
并处理
WebClientResponseException

webClient
        .method(GET)
        .uri("http://somewhere.com")
        .retrieve()
        .bodyToFlux(DataBuffer.class)
        .onErrorResume(WebClientResponseException.class, ex -> {
            if (ex.getStatusCode().equals(HttpStatus.NOT_FOUND)) {
                // ignore 404 and return empty
                return Mono.empty();
            }

            return Mono.error(ex);
        });

Option 2. 使用

onStatus
方便的方法来访问响应。

webClient
        .method(GET)
        .uri("http://somewhere.com")
        .retrieve()
        .onStatus(status -> status.equals(HttpStatus.NOT_FOUND), res -> {
            // ignore 404 and return empty
            return Mono.empty();
        })
        .bodyToFlux(DataBuffer.class)

两种方法都可用于反序列化错误响应使用 Spring WebClient 在错误情况下获取响应主体


0
投票

你可以使用

.retrieve()
.toEntityFlux(DataBuffer.class)
.map(...)

当然在这个解决方案中,首先一个 ResponseEntity 是由 spring 创建的,他们将它映射到另一个,但我没有找到更好的解决方案。

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