Spring RestTemplate - 如何设置连接超时和读取超时

时间:2015-04-14 06:46:20

标签: spring-mvc

我正在使用Spring 3.0.5版本的RestTemplate 任何人都可以帮我。如何为每个请求设置connecttimeout和readTimeout值

但是在最新版本中有一个使用HttpComponentsClientHttpRequestFactory类的解决方案。但我需要spring.web.3.0.5版本

6 个答案:

答案 0 :(得分:8)

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

答案 1 :(得分:4)

我正在使用Spring 5.2,并获得了为RestTemplate对象设置读取和连接超时设置的干净方法:

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        return builder
            .setConnectTimeout(Duration.ofMillis(connectTimeoutMillis))
            .setReadTimeout(Duration.ofMillis(readTimeoutMillis))
            .build();
    }

答案 2 :(得分:2)

您可以在

中进行设置
org.springframework.http.client.HttpComponentsClientHttpRequestFactory

或在另一个ClientHttpRequestFactory实现中。

使用

配置RestTemplate
restTemplate.setRequestFactory

或将其配置为bean属性。

答案 3 :(得分:0)

您可以使用替代解决方案(spring_web-3.0.5问题),例如 Spring SpringTemplate类通过构造CommonsClientHttpRequestFactory在内部使用HttpClient.java(commons-httpClients-3.1.jar),因此您可以将其配置为设置属性connectionTimeOut和soTimeout。见配置

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

答案 4 :(得分:0)

@Configuration
public class AppConfig {

    @Bean
    public RestTemplate restTemplate() {

        var factory = new SimpleClientHttpRequestFactory();

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

        return new RestTemplate(factory);
    }
}

答案 5 :(得分:0)

@SimonLogic 我使用下面的代码打印超时记录。当然,您可以修改它以将它们返回给调用者。

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