Spring RestTemplate - How to set connect timeout and read time out
Asked Answered
F

7

9

I am using spring 3.0.5 version of RestTemplate Can any one help me .how to set connecttimeout and readTimeout values for each request

but in latest versions there is a solution with HttpComponentsClientHttpRequestFactory class .but i need with spring.web.3.0.5 version

Freesia answered 14/4, 2015 at 6:46 Comment(0)
R
11

I am using Spring 5.2 and got clean way of setting read and connect timeout settings for RestTemplate object:

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        return builder
            .setConnectTimeout(Duration.ofMillis(connectTimeoutMillis))
            .setReadTimeout(Duration.ofMillis(readTimeoutMillis))
            .build();
    }
Renatarenate answered 1/5, 2020 at 23:33 Comment(3)
does anybody know how to get system timeouts? SimpleClientHttpRequestFactory uses -1 value which means not unlimited, but system defaults.Erdei
@SimonLogic See my answer.Rematch
@SimonLogic Why not ask it as a separate question?Renatarenate
F
10
private void setTimeout(RestTemplate restTemplate, int timeout) {
    //Explicitly setting ClientHttpRequestFactory instance to     
    //SimpleClientHttpRequestFactory instance to leverage 
    //set*Timeout methods
    restTemplate.setRequestFactory(new SimpleClientHttpRequestFactory());
    SimpleClientHttpRequestFactory rf = (SimpleClientHttpRequestFactory) restTemplate
            .getRequestFactory();
    rf.setReadTimeout(timeout);
    rf.setConnectTimeout(timeout);
}
Forficate answered 14/4, 2015 at 7:1 Comment(6)
In my version these methods are not availabaleFreesia
Please clarify what version do you use ? Its possible that your default request factory is not SimpleClientHttpRequestFactory. In that case, you might encounter run-tim issues as well. So, set the requestFactory for your RestTemplate to SimpleClientHttpRequestFactory as restTemplate.setRequestFactory(new SimpleClientHttpRequestFactory()) before invoking the method I explainedForficate
we are using Spring -web 3.0.5 version, so in that above methods are not availableFreesia
It is possible that your RestTemplate could be using and instance of ClientHttpRequestFactory other than SimpleClientHttpRequestFactory. You could try explicitly setting this at the beginning of this method. I shall edit the code above. You may try it now. Please note that SimpleClientHttpRequestFactory is available for 3.0 onwards and hence you won't face any issues.Forficate
Yes Balaji SimpleClientHttpRequestFactory is available from version 3.0. onwards. but in that version rf.setReadTimeout(timeout); rf.setConnectTimeout(timeout); methods are not availableFreesia
I see that these methods available from 3.0.6 onwards. You could try upgrading your artifacts to this version docs.spring.io/spring/docs/3.0.6.RELEASE/javadoc-api/…Forficate
D
8
@Configuration
public class AppConfig {

    @Bean
    public RestTemplate restTemplate() {

        var factory = new SimpleClientHttpRequestFactory();

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

        return new RestTemplate(factory);
    }
}
Datura answered 22/4, 2019 at 11:54 Comment(0)
C
2

You can set it in

org.springframework.http.client.HttpComponentsClientHttpRequestFactory

or in another ClientHttpRequestFactory implementation.

To configure it for RestTemplate use

restTemplate.setRequestFactory

or configure it as bean property.

Chaille answered 14/4, 2015 at 6:53 Comment(0)
R
1

@SimonLogic I use the following code to print timeouts to log. And of course you can modify it to return them back to caller.

@Slf4j
public class RestTemplateInspectionUtil {
  public static void inspectTimeouts(RestTemplate restTemplate) {
    try {
      var requestFactory = restTemplate.getRequestFactory();
      if (requestFactory instanceof AbstractClientHttpRequestFactoryWrapper) {
        Field requestFactoryField = AbstractClientHttpRequestFactoryWrapper.class.getDeclaredField("requestFactory");
        requestFactoryField.setAccessible(true);
        requestFactory = (ClientHttpRequestFactory) requestFactoryField.get(requestFactory);
      }
      if (requestFactory instanceof HttpComponentsClientHttpRequestFactory) {
        HttpClient httpClient = ((HttpComponentsClientHttpRequestFactory) requestFactory).getHttpClient();
        Method createRequestConfigMethod =
            HttpComponentsClientHttpRequestFactory.class.getDeclaredMethod("createRequestConfig", Object.class);
        createRequestConfigMethod.setAccessible(true);
        RequestConfig requestConfig = (RequestConfig) createRequestConfigMethod.invoke(requestFactory, httpClient);
        log.debug("socket (read) timeout: {}, connection timeout: {}, connection request timeout: {}",
            requestConfig.getSocketTimeout(), requestConfig.getConnectTimeout(), requestConfig.getConnectionRequestTimeout());
      } else if (requestFactory instanceof SimpleClientHttpRequestFactory) {
        Field readTimeoutField = requestFactory.getClass().getDeclaredField("readTimeout");
        readTimeoutField.setAccessible(true);
        Field connectTimeoutField = requestFactory.getClass().getDeclaredField("connectTimeout");
        connectTimeoutField.setAccessible(true);
        int readTimeout = readTimeoutField.getInt(requestFactory);
        int connectTimeout = connectTimeoutField.getInt(requestFactory);
        log.debug("read timeout: {}, connection timeout: {}", readTimeout, connectTimeout);
      }
    } catch (Exception ex) {
      log.debug("Failed to check restTemplate timeouts: {}", ex);
    }
  }
}
Rematch answered 1/7, 2021 at 3:27 Comment(0)
M
0

You can use an alternative solution (issue with spring_web-3.0.5),like The spring RestTemplate class internally uses the HttpClient.java (commons-httpClients-3.1.jar) by constructing CommonsClientHttpRequestFactory, so you can configure it for setting the property connectionTimeOut and soTimeout . see the configuration

<bean id="httpClient" class="org.apache.commons.httpclient.HttpClient">
 <constructor-arg>
  <bean  class="org.apache.commons.httpclient.MultiThreadedHttpConnectionManager">
   <property name="params">
   <bean      class="org.apache.commons.httpclient.params.HttpConnectionManagerParams">
    <property name="connectionTimeout" value="2000" />
     <!-- <property name="soTimeout" value="2000" />
     soTimeout is same as readTimeout which is used for socket timeout that  waiting for data -->
     </bean>
   </property>
  </bean>
 </constructor-arg>
 </bean>
  <bean id="httpComponentsClientHttpRequestFactory"
    class="org.springframework.http.client.CommonsClientHttpRequestFactory">
  <constructor-arg ref="httpClient" />
   <property name="readTimeout" value="2000"/>
   </bean>

<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
<constructor-arg ref="httpComponentsClientHttpRequestFactory" />
</bean>
Misdirect answered 18/11, 2015 at 15:6 Comment(0)
G
0

Step 1: Create a function

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

Step 2:

RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());
Gendron answered 1/6, 2023 at 13:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.