Spring RestTemplate超时
我想为我的Web应用程序使用的其他服务设置连接超时。 我正在使用Spring的RestTemplate与我的服务交谈。 我已经做了一些研究,我已经find并使用下面的XML(在我的应用程序的XML),我相信是用来设置超时。 我正在使用Spring 3.0。
我也看到了同样的问题在这里用RestTemplate的springwebservices超时configuration,但解决scheme似乎并不干净 ,我宁愿设置超时值通过Springconfiguration
<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秒,并报告以下exception:
org.springframework.web.client.ResourceAccessExcep tion:I / O错误:没有路由到主机:连接; 嵌套exception是java.net.NoRouteToHostException:没有路由到主机:连接
Url不正确,所以404由rest服务返回:等待大约10秒,并报告以下exception:
org.springframework.web.client.HttpClientErrorException:404 Not Found
我的要求要求更短的超时,所以我需要能够改变这些。 任何想法,我做错了什么?
非常感谢。
对于使用@Configuration
而不是XML
Spring 4
@Configuration public class AppConfig { @Bean public RestTemplate customRestTemplate() { HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(); httpRequestFactory.setConnectionRequestTimeout(...); httpRequestFactory.setConnectTimeout(...); httpRequestFactory.setReadTimeout(...); return new RestTemplate(httpRequestFactory); } }
春季启动
@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
,因为HttpComponentsClientHttpRequestFactory
具有公共设置程序connectionRequestTimeout
, connectTimeout
, readTimeout
和@ConfigurationProperties
为您设置它们。
我终于得到了这个工作。
我认为我们的项目有两个不同版本的commons-httpclient jar没有帮助。 一旦我整理出来,我发现你可以做两件事情…
在代码中,你可以把以下内容:
HttpComponentsClientHttpRequestFactory rf = (HttpComponentsClientHttpRequestFactory) restTemplate.getRequestFactory(); rf.setReadTimeout(1 * 1000); rf.setConnectTimeout(1 * 1000);
第一次调用这段代码时,它将设置RestTemplate
使用的HttpComponentsClientHttpRequestFactory
类的超时时间。 因此, RestTemplate
所做的后续调用将使用上面定义的超时设置。
或者更好的select是做到这一点:
<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
接口,并从属性文件中获取超时值。
这是一个非常简单的方法来设置超时:
RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory()); private ClientHttpRequestFactory getClientHttpRequestFactory() { int timeout = 5000; HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(); clientHttpRequestFactory.setConnectTimeout(timeout); return clientHttpRequestFactory; }
这个问题是Spring Bootsearch的第一个链接,因此,将官方文档中推荐的解决scheme放在这里是非常好的。 Spring Boot有自己的便捷bean RestTemplateBuilder :
@Bean public RestTemplate restTemplate( RestTemplateBuilder restTemplateBuilder) { return restTemplateBuilder .setConnectTimeout(500) .setReadTimeout(500) .build(); }
手动创buildRestTemplate实例是一个潜在的麻烦方法,因为其他自动configuration的Bean没有被注入到手动创build的实例中。
我有一个类似的情况,但也需要设置一个代理服务器。 我能看到的最简单的方法就是扩展SimpleClientHttpRequestFactory
,以方便设置代理(非prod和prod的不同代理)。 即使你不需要代理,这应该仍然有效。 然后在我的扩展类中,我重写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; }