Spring RestTemplate timeout
For Spring Boot >= 1.4
@Configurationpublic class AppConfig{ @Bean public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) { return restTemplateBuilder .setConnectTimeout(...) .setReadTimeout(...) .build(); }}
For Spring Boot <= 1.3
@Configurationpublic 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
@Configurationpublic 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:
@Beanpublic 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.