Spring 5 Webflux如何为现有Web客户端设置超时

时间:2019-07-14 12:53:03

标签: java spring spring-webflux reactor reactor-netty

我在配置类中定义了一个WebClient bean。它需要对其连接器进行大量配置(包括设置SSL,代理等)。

    @Bean
    @Primary
    @Scope("prototype")
    public WebClient webClient()
    {
       SslContextBuilder builder = SslContextBuilder.forClient();
        HttpClient httpClient = HttpClient
                .create(ConnectionProvider.fixed("webClientPool", maxConnections))
                ...

        ReactorClientHttpConnector connector = new ReactorClientHttpConnector(httpClient);
        WebClient webClient = WebClient.builder()
                .clientConnector(connector)
                .exchangeStrategies(getExchangeStrategies())
                .build();
        return webClient;

在要注入此WebClient的bean中,我要设置不同的超时。

我本来想使用webClient.mutate().clientConnector(...)方法,但这将要求我从头开始设置整个配置,只是为了设置超时。 不幸的是,WebClient和HttpClient没有.getxxx()方法可以帮助我将旧的客户端配置复制到新的客户端中。

我想有一种方法只为tcp-client的超时选项设置为变异的WebClient。 有办法吗?

2 个答案:

答案 0 :(得分:1)

根据文档

  

WebClient.Builder mutate()

     

返回构建器以创建一个新的WebClient,其设置将从当前WebClient复制。

将返回一个具有所有先前设置的新生成器,因此您无需复制任何内容。

webclient mutate

如果您想尽可能减少配置,您可以:

定义一个 hSession = WinHttpOpen( L"ODD", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, WINHTTP_FLAG_ASYNC); if (hSession) hConnect = WinHttpConnect( hSession, L"login.live.com", INTERNET_DEFAULT_HTTPS_PORT, 0); if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL, NULL, WINHTTP_NO_REFERER, NULL, WINHTTP_FLAG_SECURE); if (hRequest) bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); if (bResults) bResults = WinHttpReceiveResponse(hRequest, NULL); if (bResults) { WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, NULL, &dwSize, WINHTTP_NO_HEADER_INDEX); // Allocate memory for the buffer. if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { lpOutBuffer = new WCHAR[dwSize / sizeof(WCHAR)]; // Now, use WinHttpQueryHeaders to retrieve the header. bResults = WinHttpQueryHeaders( hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, lpOutBuffer, &dwSize, WINHTTP_NO_HEADER_INDEX); } } cout << bResults << endl; if (bResults) printf("=================================================\nHeader contents: \n%S=================================================", lpOutBuffer); ,在其中尽可能多地配置@Bean,以便以后可以在HttpClient.Builder中自动装配

然后,您定义2个Web客户端,这些Web客户端会自动绑定到httpclient中,并将httpclient.build()完成到每个Webclient中。

或者您定义一个Web客户端,然后在需要修改的Web客户端的类中,将其注入到Web客户端和httpclient.builder中,并完成配置并更改Web客户端。

答案 1 :(得分:-1)

您可以使用reactor.core.publisher.Mono#timeout(java.time.Duration)方法,而不用修改WebClient

webClient.get()
        .uri("http://whatever/path")
        .retrieve()
        .bodyToMono(String.class)
        .timeout(Duration.ofMillis(3000));

编辑:基础连接将被清除

21:53:11.380 [parallel-1] DEBUG org.springframework.web.reactive.function.client.ExchangeFunctions - [7ed3df3b] Cancel signal (to close connection)
21:53:11.382 [reactor-http-epoll-5] DEBUG reactor.netty.http.client.HttpClient - [id: 0xd97cbbde, L:/127.0.0.1:39140 - R:localhost/127.0.0.1:44451] CLOSE
21:53:11.384 [reactor-http-epoll-5] DEBUG reactor.netty.resources.PooledConnectionProvider - [id: 0xd97cbbde, L:/127.0.0.1:39140 ! R:localhost/127.0.0.1:44451] Channel cleaned, now 0 active connections and 1 inactive connections