弹簧安置模板超时(Spring RestTemplate timeout)

2019-07-05 00:51发布

我想设置连接超时通过我的web应用程序中使用REST服务。 我使用Spring的RestTemplate谈谈我的服务。 我做了一些研究,我发现和使用下面的XML(在我的应用XML),我相信是为了设置超时。 我使用Spring 3.0。

我也看到了这里同样的问题与RestTemplate春天web服务超时配置 ,但解决方案似乎并不干净 ,我宁愿通过Spring配置来设置超时值

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

看来,无论我设置readTimeout是我得到以下几点:

网线断开:等待大约20秒和报告以下情况除外:

org.springframework.web.client.ResourceAccessExcep重刑:I / O错误:没有到主机的路由:连接; 嵌套的例外是java.net.NoRouteToHostException:到主机的路由:连接

地址不正确因此由404 REST服务返回:等待大约10秒,并报告以下情况除外:

org.springframework.web.client.HttpClientErrorException:404未找到

我的要求,需要更短的超时,所以我需要能够改变这些。 任何想法,我做错了什么?

非常感谢。

Answer 1:

春季启动> = 1.4

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

对于弹簧引导<= 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());
    }
}

然后在您的application.properties

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

这工作,因为HttpComponentsClientHttpRequestFactory具有公共setter方法connectionRequestTimeoutconnectTimeoutreadTimeout@ConfigurationProperties设置它们。


春季4.1或5春春不使用引导 @Configuration而不是XML

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

        return new RestTemplate(httpRequestFactory);
    }
}


Answer 2:

我终于得到了这个工作。

我认为一个事实,即我们的项目有两个不同版本的公地httpclient的罐子并没有帮助。 一旦我整理了这一点,我发现你可以做两件事情...

在代码中你可以把以下内容:

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

第一次遇到这种代码被称为它将设置为超时HttpComponentsClientHttpRequestFactory由所使用的类RestTemplate 。 因此,提出的所有后续调用RestTemplate将使用上面定义的超时设置。

或者更好的选择是这样做:

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

当我使用RestOperations接口在我的代码,并从属性文件中获取的超时值。



Answer 3:

这个问题是第一个链接,一个Spring引导搜索,因此,将是巨大的,放在这里的官方文档中推荐的解决方案 。 春季启动有它自己的便利豆RestTemplateBuilder :

@Bean
public RestTemplate restTemplate(
        RestTemplateBuilder restTemplateBuilder) {

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

手动创建RestTemplate实例是一个潜在的麻烦的方法,因为其他自动配置的bean没有被手动创建的实例注入。



Answer 4:

这里是一个非常简单的方法来设置超时:

RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());

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


Answer 5:

这里是我的2美分。 什么新鲜事,但一些解释,改进和更新的代码。

默认情况下, RestTemplate具有无限超时。 有两种类型的超时:连接超时和读超时。 例如,我可以连接到服务器,但我无法读取数据。 申请被挂,你不知道发生了什么事情。

我将使用注释,这些日子优于XML。

@Configuration
public class AppConfig {

    @Bean
    public RestTemplate restTemplate() {

        var factory = new SimpleClientHttpRequestFactory();

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

        return new RestTemplate(factory);
    }
}

这里我们使用SimpleClientHttpRequestFactory设置连接和读取超时。 然后,它被传递到构造RestTemplate

@Configuration
public class AppConfig {

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {

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

在第二个解决方案,我们使用RestTemplateBuilder 。 还要注意两种方法的参数:他们需要Duration 。 现在直接在几毫秒的重载的方法已被弃用。

Edit(编辑)测试与Spring 2.1.0引导和Java 11。



Answer 6:

我也有类似的情况,但还需要设置一个代理。 我可以看到这样做的最简单方法是延长SimpleClientHttpRequestFactory为了便于设置代理(非督促VS督促不同的代理)的。 这应该仍然工作,即使你不需要代理虽然。 然后在我的扩展类我重写openConnection(URL url, Proxy proxy)的方法,使用相同的来源 ,但在返回前刚刚设定的超时。

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


文章来源: Spring RestTemplate timeout