Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring RestTemplate timeout

People also ask

What is the default timeout for Spring RestTemplate?

The default timeout is infinite. By default RestTemplate uses SimpleClientHttpRequestFactory and that in turn uses HttpURLConnection.

How do you set a request timeout for RestTemplate?

RestTemplate default timeoutprivate int connectTimeout = - 1 ; private int readTimeout = - 1 ; By default, resttemplate uses timeout property from JDK installed on the machine which is always infinite in not overridden. To override the default JVM timeout, we can pass these properties during JVM start.

What is connection timeout and read time RestTemplate?

Connection timeout is used when opening a communications link to the remote resource. A java.net.SocketTimeoutException is thrown if the timeout expires before the connection can be established. Read timeout is used when reading from Input Stream when a connection is established to a remote resource.


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 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.


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.


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;
}

  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