[spring] Spring RestTemplate timeout

I would like to set the connection timeouts for a rest service used by my web application. I'm using Spring's RestTemplate to talk to my service. I've done some research and I've found and used the xml below (in my application xml) which I believe is meant to set the timeout. I'm using Spring 3.0.

I've also seen the same problem here Timeout configuration for spring webservices with RestTemplate but the solutions don't seem that clean, I'd prefer to set the timeout values via Spring config

<bean id="RestOperations" class="org.springframework.web.client.RestTemplate">
    <constructor-arg>

      <bean class="org.springframework.http.client.CommonsClientHttpRequestFactory">
        <property name="readTimeout" value="${restURL.connectionTimeout}" />
      </bean>
    </constructor-arg>
</bean>

It seems whatever I set the readTimeout to be I get the following:

Network cable disconnected: Waits about 20 seconds and reports following exception:

org.springframework.web.client.ResourceAccessExcep tion: I/O error: No route to host: connect; nested exception is java.net.NoRouteToHostException: No route to host: connect

Url incorrect so 404 returned by rest service: Waits about 10 seconds and reports following exception:

org.springframework.web.client.HttpClientErrorException: 404 Not Found

My requirements require shorter timeouts so I need to be able to change these. Any ideas as to what I'm doing wrong?

Many thanks.

This question is related to spring rest timeout resttemplate

The answer is


I finally got this working.

I think the fact that our project had two different versions of the commons-httpclient jar wasn't helping. Once I sorted that out I found you can do two things...

In code you can put the following:

HttpComponentsClientHttpRequestFactory rf =
    (HttpComponentsClientHttpRequestFactory) restTemplate.getRequestFactory();
rf.setReadTimeout(1 * 1000);
rf.setConnectTimeout(1 * 1000);

The first time this code is called it will set the timeout for the HttpComponentsClientHttpRequestFactory class used by the RestTemplate. Therefore, all subsequent calls made by RestTemplate will use the timeout settings defined above.

Or the better option is to do this:

<bean id="RestOperations" class="org.springframework.web.client.RestTemplate">
    <constructor-arg>
        <bean class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
            <property name="readTimeout" value="${application.urlReadTimeout}" />
            <property name="connectTimeout" value="${application.urlConnectionTimeout}" />
        </bean>
    </constructor-arg>
</bean>

Where I use the RestOperations interface in my code and get the timeout values from a properties file.


This question is the first link for a Spring Boot search, therefore, would be great to put here the solution recommended in the official documentation. Spring Boot has its own convenience bean RestTemplateBuilder:

@Bean
public RestTemplate restTemplate(
        RestTemplateBuilder restTemplateBuilder) {

    return restTemplateBuilder
            .setConnectTimeout(Duration.ofSeconds(500))
            .setReadTimeout(Duration.ofSeconds(500))
            .build();
}

Manual creation of RestTemplate instances is a potentially troublesome approach because other auto-configured beans are not being injected in manually created instances.


  1. RestTemplate timeout with SimpleClientHttpRequestFactory To programmatically override the timeout properties, we can customize the SimpleClientHttpRequestFactory class as below.

Override timeout with SimpleClientHttpRequestFactory

//Create resttemplate
RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());

//Override timeouts in request factory
private SimpleClientHttpRequestFactory getClientHttpRequestFactory() 
{
    SimpleClientHttpRequestFactory clientHttpRequestFactory
                      = new SimpleClientHttpRequestFactory();
    //Connect timeout
    clientHttpRequestFactory.setConnectTimeout(10_000);

    //Read timeout
    clientHttpRequestFactory.setReadTimeout(10_000);
    return clientHttpRequestFactory;
}
  1. RestTemplate timeout with HttpComponentsClientHttpRequestFactory SimpleClientHttpRequestFactory helps in setting timeout but it is very limited in functionality and may not prove sufficient in realtime applications. In production code, we may want to use HttpComponentsClientHttpRequestFactory which support HTTP Client library along with resttemplate.

HTTPClient provides other useful features such as connection pool, idle connection management etc.

Read More : Spring RestTemplate + HttpClient configuration example

Override timeout with HttpComponentsClientHttpRequestFactory

//Create resttemplate
RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());

//Override timeouts in request factory
private SimpleClientHttpRequestFactory getClientHttpRequestFactory() 
{
    HttpComponentsClientHttpRequestFactory clientHttpRequestFactory
                      = new HttpComponentsClientHttpRequestFactory();
    //Connect timeout
    clientHttpRequestFactory.setConnectTimeout(10_000);

    //Read timeout
    clientHttpRequestFactory.setReadTimeout(10_000);
    return clientHttpRequestFactory;
}

reference: Spring RestTemplate timeout configuration example


To expand on benscabbia's answer:

private RestTemplate restCaller = new RestTemplate(getClientHttpRequestFactory());

private ClientHttpRequestFactory getClientHttpRequestFactory() {
    int connectionTimeout = 5000; // milliseconds
    int socketTimeout = 10000; // milliseconds
    RequestConfig config = RequestConfig.custom()
      .setConnectTimeout(connectionTimeout)
      .setConnectionRequestTimeout(connectionTimeout)
      .setSocketTimeout(socketTimeout)
      .build();
    CloseableHttpClient client = HttpClientBuilder
      .create()
      .setDefaultRequestConfig(config)
      .build();
    return new HttpComponentsClientHttpRequestFactory(client);
}

Here is a really simple way to set the timeout:

RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());

private ClientHttpRequestFactory getClientHttpRequestFactory() {
    int timeout = 5000;
    HttpComponentsClientHttpRequestFactory clientHttpRequestFactory =
      new HttpComponentsClientHttpRequestFactory();
    clientHttpRequestFactory.setConnectTimeout(timeout);
    return clientHttpRequestFactory;
}

For Spring Boot >= 1.4

@Configuration
public class AppConfig
{
    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) 
    {
        return restTemplateBuilder
           .setConnectTimeout(...)
           .setReadTimeout(...)
           .build();
    }
}

For Spring Boot <= 1.3

@Configuration
public class AppConfig
{
    @Bean
    @ConfigurationProperties(prefix = "custom.rest.connection")
    public HttpComponentsClientHttpRequestFactory customHttpRequestFactory() 
    {
        return new HttpComponentsClientHttpRequestFactory();
    }

    @Bean
    public RestTemplate customRestTemplate()
    {
        return new RestTemplate(customHttpRequestFactory());
    }
}

then in your application.properties

custom.rest.connection.connection-request-timeout=...
custom.rest.connection.connect-timeout=...
custom.rest.connection.read-timeout=...

This works because HttpComponentsClientHttpRequestFactory has public setters connectionRequestTimeout, connectTimeout, and readTimeout and @ConfigurationProperties sets them for you.


For Spring 4.1 or Spring 5 without Spring Boot using @Configuration instead of XML

@Configuration
public class AppConfig
{
    @Bean
    public RestTemplate customRestTemplate()
    {
        HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
        httpRequestFactory.setConnectionRequestTimeout(...);
        httpRequestFactory.setConnectTimeout(...);
        httpRequestFactory.setReadTimeout(...);

        return new RestTemplate(httpRequestFactory);
    }
}

I had a similar scenario, but was also required to set a Proxy. The simplest way I could see to do this was to extend the SimpleClientHttpRequestFactory for the ease of setting the proxy (different proxies for non-prod vs prod). This should still work even if you don't require the proxy though. Then in my extended class I override the openConnection(URL url, Proxy proxy) method, using the same as the source, but just setting the timeouts before returning.

@Override
protected HttpURLConnection openConnection(URL url, Proxy proxy) throws IOException {
    URLConnection urlConnection = proxy != null ? url.openConnection(proxy) : url.openConnection();
    Assert.isInstanceOf(HttpURLConnection.class, urlConnection);
    urlConnection.setConnectTimeout(5000);
    urlConnection.setReadTimeout(5000);
    return (HttpURLConnection) urlConnection;
}

Here are my 2 cents. Nothing new, but some explanations, improvements and newer code.

By default, RestTemplate has infinite timeout. There are two kinds of timeouts: connection timeout and read time out. For instance, I could connect to the server but I could not read data. The application was hanging and you have no clue what's going on.

I am going to use annotations, which these days are preferred over XML.

@Configuration
public class AppConfig {

    @Bean
    public RestTemplate restTemplate() {

        var factory = new SimpleClientHttpRequestFactory();

        factory.setConnectTimeout(3000);
        factory.setReadTimeout(3000);

        return new RestTemplate(factory);
    }
}

Here we use SimpleClientHttpRequestFactory to set the connection and read time outs. It is then passed to the constructor of RestTemplate.

@Configuration
public class AppConfig {

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {

        return builder
                .setConnectTimeout(Duration.ofMillis(3000))
                .setReadTimeout(Duration.ofMillis(3000))
                .build();
    }
}

In the second solution, we use the RestTemplateBuilder. Also notice the parameters of the two methods: they take Duration. The overloaded methods that take directly milliseconds are now deprecated.

Edit Tested with Spring Boot 2.1.0 and Java 11.


Examples related to spring

Are all Spring Framework Java Configuration injection examples buggy? Two Page Login with Spring Security 3.2.x Access blocked by CORS policy: Response to preflight request doesn't pass access control check Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean Failed to auto-configure a DataSource: 'spring.datasource.url' is not specified Spring Data JPA findOne() change to Optional how to use this? After Spring Boot 2.0 migration: jdbcUrl is required with driverClassName The type WebMvcConfigurerAdapter is deprecated No converter found capable of converting from type to type

Examples related to rest

Access blocked by CORS policy: Response to preflight request doesn't pass access control check Returning data from Axios API Access Control Origin Header error using Axios in React Web throwing error in Chrome JSON parse error: Can not construct instance of java.time.LocalDate: no String-argument constructor/factory method to deserialize from String value How to send json data in POST request using C# How to enable CORS in ASP.net Core WebAPI RestClientException: Could not extract response. no suitable HttpMessageConverter found REST API - Use the "Accept: application/json" HTTP Header 'Field required a bean of type that could not be found.' error spring restful API using mongodb MultipartException: Current request is not a multipart request

Examples related to timeout

Waiting for Target Device to Come Online Spring Boot Java Config Set Session Timeout How to dispatch a Redux action with a timeout? Spring Boot REST API - request timeout? 5.7.57 SMTP - Client was not authenticated to send anonymous mail during MAIL FROM error How to set timeout in Retrofit library? How to set connection timeout with OkHttp How to modify the nodejs request default timeout time? How to handle ETIMEDOUT error? Timeout for python requests.get entire response

Examples related to resttemplate

RestClientException: Could not extract response. no suitable HttpMessageConverter found How to POST form data with Spring RestTemplate? Spring Resttemplate exception handling Could not autowire field:RestTemplate in Spring boot application RestTemplate: How to send URL and query parameters together How to autowire RestTemplate using annotations Multipart File Upload Using Spring Rest Template + Spring Web MVC Could not read JSON: Can not deserialize instance of hello.Country[] out of START_OBJECT token Get list of JSON objects with Spring RestTemplate How to disable SSL certificate checking with Spring RestTemplate?