当前位置: 首页 > 知识库问答 >
问题:

如何在Spring WebClient中设置和处理超时?

贺亦
2023-03-14

Spring docs表示,需要手动为WebClient配置http客户机以设置超时:https://docs.Spring.io/Spring/docs/current/spring-framework-reference/web-reactive.html#webflux-client-builder-reactor-timeout。但是,由于WebClient返回反应单声道,所以可以(在API方面)应用.timeout方法。

有同样的效果吗?

此外,当使用.timeout方法时,需要reactor的timeoutexception。如果手动进行配置,流中会出现相同的错误吗?例如doonerror(timeoutexception.class,...)会工作吗?

共有1个答案

卓新知
2023-03-14

我的发现

以特定于http客户端的方式设置超时将导致特定于http客户端的异常,即WebClient不包装异常:

@Test
void test() {
    var host = "localhost";
    var endpoint = "/test";
    var port = 8089;
    var timeout = Duration.ofSeconds(3);

    WireMockServer wireMockServer = new WireMockServer(wireMockConfig().port(8089));
    wireMockServer.start();
    WireMock.configureFor(host, wireMockServer.port());

    WireMock.stubFor(get(urlEqualTo(endpoint))
        .willReturn(aResponse().withFixedDelay((int) timeout.toMillis())));

    HttpClient httpClient = HttpClient.create()
        .tcpConfiguration(client ->
            client.doOnConnected(conn -> conn
                .addHandlerLast(new ReadTimeoutHandler((int) (timeout.toSeconds() / 2)))
                .addHandlerLast(new WriteTimeoutHandler((int) (timeout.toSeconds() / 2)))));

    WebClient webClient = WebClient.builder()
        .baseUrl(format("http://%s:%d", host, port))
        .clientConnector(new ReactorClientHttpConnector(httpClient)).build();

    webClient.get().uri(endpoint).retrieve().bodyToMono(Recommendation.class).block();
}

这将导致io.netty.handler.timeout.ReadTimeoutException

.timeout(timeout.dividedby(2)).block()导致常规的timeoutexception(java.util.concurrent),但是web客户机之后是否会关心连接仍然是一个悬而未决的问题(可能不会)。

我的解决方案是使用特定于http客户机的配置来确保以本机和正确的方式利用连接,同时添加新的处理程序,该处理程序将http客户机相关的异常包装成更通用的异常(或java.util.concurrent.TimeoutException),这样WebClient客户机就不会依赖于提供程序异常。

 类似资料:
  • 问题内容: 我org.springframework.ws.client.core.WebServiceTemplate用于拨打Web服务。如何为通话配置超时。 问题答案: 如果你使用的是Spring Webservices 2.1.0版本,则可以使用HttpComponentsMessageSender设置超时。 Spring不推荐使用CommonsHttpMessageSender,因此不再推

  • 我正在尝试在我的WebClient上设置超时,以下是当前代码: 我需要添加超时和池策略,我在想这样的事情: 但是我不知道如何在我的webclient中设置httpClient

  • 问题内容: 我正在尝试在控制器中设置超时,以便如果在250毫秒内未收到响应,它将失败。我将单元测试的超时设置为10000,这样就可以满足此条件,有人可以指出正确的方向吗?(编辑,我试图在不使用$ http服务的情况下实现这一点,我知道该服务提供超时功能) (编辑- 我的其他单元测试失败了,因为我没有在它们上调用timeout.flush,现在我只需要在promiseService.getPromi

  • 问题内容: 我在我的应用程序中使用Retrofit库,我想将超时设置为60秒。改装有某种方法可以做到这一点吗? 我以这种方式设置Retrofit: 如何设置超时时间? 问题答案: 您可以在基础HTTP客户端上设置超时。如果未指定客户端,则Retrofit将使用默认的连接和读取超时创建一个客户端。要设置自己的超时时间,您需要配置自己的客户端并将其提供给。 一种选择是使用也是来自Square 的OkH

  • 但我想要的是这样的