首页 文章

Webclient响应处理程序(成功和错误)不会为空响应主体执行

提问于
浏览
0

使用OkHttp实现异步REST API客户端,工作得很好 . 试图出于好奇心将其转换为WebClient,观察奇怪的行为 .

WebClient配置就是这样的:

webClient = WebClient.builder()
    .defaultHeaders(headers -> headers.add(HttpHeaders.CONTENT_TYPE,
        org.springframework.http.MediaType.APPLICATION_JSON_VALUE))
    .clientConnector(new ReactorClientHttpConnector(builder -> builder
        .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, timeout)))
    .build();

请求代码:

void getTokenWithWebClient(Consumer<Try<String>> callback) {
    webClient.post()
        .uri(url)
        .syncBody(new MyRequest())
        .retrieve()
        .onStatus(status -> status.value() != HttpStatus.OK.value(),
            rs -> rs.bodyToMono(String.class).map(body -> new IOException(String.format(
                "Response HTTP code is different from 200: %s, body: '%s'", rs.statusCode(), body))))
        .bodyToMono(MyResponse.class)
        .subscribe(rs -> callback.accept(Try.of(() -> validateResponse(Option.of(rs)))),
            ex -> callback.accept(Try.failure(ex)));
}

在单元测试中,作为参数传递给此方法的回调完成了一个Future,我等待 . 因此,当我在IDEA中进行测试,并且请求导致空体(内容长度:0)的响应时,subscribe()中的lambdas永远不会执行 - 使用println调试验证 .

但是当我 debug 相同的测试时,即使没有设置任何断点,它也会按预期完成,并根据结果调用lambdas .

我在日志中看到了这个:

[reactor-http-nio-4] DEBUG reactor.ipc.netty.http.client.HttpClientOperations - [id: 0xeffaded6, L:/127.0.0.1:49265 - R:localhost/127.0.0.1:58522] Received last HTTP packet
[reactor-http-nio-4] DEBUG reactor.ipc.netty.http.client.HttpClient - [id: 0xeffaded6, L:/127.0.0.1:49265 - R:localhost/127.0.0.1:58522] USER_EVENT: [Handler Terminated]
[reactor-http-nio-4] DEBUG reactor.ipc.netty.channel.ChannelOperationsHandler - [id: 0xeffaded6, L:/127.0.0.1:49265 - R:localhost/127.0.0.1:58522] Disposing context reactor.ipc.netty.channel.PooledClientContextHandler@3547abe3
[reactor-http-nio-4] DEBUG reactor.ipc.netty.channel.PooledClientContextHandler - Releasing channel: [id: 0xeffaded6, L:/127.0.0.1:49265 - R:localhost/127.0.0.1:58522]
[reactor-http-nio-4] DEBUG reactor.ipc.netty.resources.DefaultPoolResources - Released [id: 0xeffaded6, L:/127.0.0.1:49265 - R:localhost/127.0.0.1:58522], now 0 active connections
[reactor-http-nio-4] DEBUG reactor.ipc.netty.http.client.HttpClient - [id: 0xeffaded6, L:/127.0.0.1:49265 - R:localhost/127.0.0.1:58522] READ COMPLETE
[reactor-http-nio-4] DEBUG reactor.ipc.netty.http.client.HttpClient - [id: 0xeffaded6, L:/127.0.0.1:49265 - R:localhost/127.0.0.1:58522] READ COMPLETE
[reactor-http-nio-4] DEBUG reactor.ipc.netty.http.client.HttpClient - [id: 0xeffaded6, L:/127.0.0.1:49265 ! R:localhost/127.0.0.1:58522] CLOSE
[reactor-http-nio-4] DEBUG reactor.ipc.netty.http.client.HttpClient - [id: 0xeffaded6, L:/127.0.0.1:49265 ! R:localhost/127.0.0.1:58522] INACTIVE
[reactor-http-nio-4] DEBUG reactor.ipc.netty.http.client.HttpClient - [id: 0xeffaded6, L:/127.0.0.1:49265 ! R:localhost/127.0.0.1:58522] UNREGISTERED

但随后我的错误Mono卡在某处 .

在Windows 7,Oracle JDK8 x64,IDEA 2018上运行此选项.Option / Try是vavr类(io.vavr:vavr),与此案例无关 . 对于单元测试,我使用Ratpack模拟有问题的REST API .

尝试使用exchange()而不是retrieve()并检查subscribe()lambda中的状态代码,而不使用onStatus() - 具有相同的结果 .

有任何想法吗?

1 回答

  • 0

    长话短说, rs.bodyToMono(String.class).defaultIfEmpty("") 救了一天

相关问题