javaspringspring-boot

Cannot resolve method 'setReadTimeout' in 'HttpComponentsClientHttpRequestFactory'


I have to migrate this Spring Boot code to latest version. After Spring 6+ setReadTimeout is deprecated.

HttpComponentsClientHttpRequestFactory factory = new 
HttpComponentsClientHttpRequestFactory();
factory.setReadTimeout(20);
factory.setConnectTimeout(20);
factory.setConnectionRequestTimeout(20);
return new RestTemplate(factory);

According to the JavaDoc: https://www.javadoc.io/static/org.springframework/spring-web/6.0.8/org/springframework/http/client/HttpComponentsClientHttpRequestFactory.html#setReadTimeout(int)

I have to use setSoTimeout but I can't find this method. What should the proper way to migrate this code?


Solution

  • The SocketConfig object, where the timeout is set, is then assigned to a PoolingHttpClientConnectionManager, which then gets assigned to a HttpClient, which is then used to initialize a HttpComponentsClientHttpRequestFactory. The complete RestTemplate bean initialization code would look something like the below:

    import org.apache.hc.client5.http.classic.HttpClient;
    import org.apache.hc.client5.http.config.ConnectionConfig;
    import org.apache.hc.client5.http.config.RequestConfig;
    import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
    import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
    import org.apache.hc.core5.http.io.SocketConfig;
    import org.apache.hc.core5.util.Timeout;
    import org.springframework.boot.web.client.RestTemplateBuilder;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
    import org.springframework.web.client.RestTemplate;
    
    @Configuration
    public class RestTemplateConfig {
    
        @Bean
        public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
            RestTemplate restTemplate = restTemplateBuilder.build();
    
            // Connect timeout
            ConnectionConfig connectionConfig = ConnectionConfig.custom()
                    .setConnectTimeout(Timeout.ofMilliseconds(20))
                    .build();
    
            // Socket timeout
            SocketConfig socketConfig = SocketConfig.custom()
                    .setSoTimeout(Timeout.ofMilliseconds(20))
                    .build();
    
            // Connection request timeout
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectionRequestTimeout(Timeout.ofMilliseconds(20))
                    .build();
    
            PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
            connectionManager.setDefaultSocketConfig(socketConfig);
            connectionManager.setDefaultConnectionConfig(connectionConfig);
    
            HttpClient httpClient = HttpClientBuilder.create()
                    .setConnectionManager(connectionManager)
                    .setDefaultRequestConfig(requestConfig)
                    .build();
            restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));
    
            return restTemplate;
        }
    }
    

    You would also need the httpclient5 dependency:

    implementation group: 'org.apache.httpcomponents.client5', name: 'httpclient5', version: '5.2.3'