Resttemplate 設置超時時長
為了滿足調用需求,需要在使用Resttemplate發送請求時,修改超時時長,網上給出了相關修改方法,代碼如下:
1
2
3
4
|
HttpComponentsClientHttpRequestFactory rf = ((HttpComponentsClientHttpRequestFactory) restTemplate.getRequestFactory()); rf.setConnectTimeout( 30000 ); rf.setReadTimeout( 30000 ); |
但是在運行時報錯:
org.springframework.http.client.InterceptingClientHttpRequestFactory cannot be cast to org.springframework.http.client.HttpComponentsClientHttpRequestFactory
restTemplate.getRequestFactory()返回的類型無法轉換,通過搜索和調試發現,在resttemplate中,必須在設置攔截器之前設置超時,因為在設置攔截器后無法設置超時,而我在設置中并沒有設置過攔截器,應該是被默認構造了
所以解決方法如下:
1
2
3
4
5
|
restTemplate.setInterceptors( null ); HttpComponentsClientHttpRequestFactory rf = ((HttpComponentsClientHttpRequestFactory) restTemplate.getRequestFactory()); rf.setConnectTimeout( 30000 ); rf.setReadTimeout( 30000 ); |
在設置超時之前,先將攔截器置空,這樣就不會出現無法設置的問題,之后驗證通過。
查看resttemplate源碼后發現,之所以會出現這樣的情況是因為在resttemplate的源碼中,有這么一段代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
/** * Return the request interceptor that this accessor uses. */ public List<ClientHttpRequestInterceptor> getInterceptors() { return interceptors; } @Override public ClientHttpRequestFactory getRequestFactory() { ClientHttpRequestFactory delegate = super .getRequestFactory(); if (!CollectionUtils.isEmpty(getInterceptors())) { return new InterceptingClientHttpRequestFactory(delegate, getInterceptors()); } else { return delegate; } } |
可以看到,在getRequestFactory()函數中,本來應該是返回ClientHttpRequestFactory類型的,但是它會先校驗一次是否含有interceptors攔截器,如果攔截器非空,則會返回包含攔截器的InterceptingClientHttpRequestFactory,這樣是無法轉換為HttpComponentsClientHttpRequestFactory類型的,因此在前面處理的時候將攔截器置空,這樣就可以返回不含攔截器的所需對象。
RestTemplate 設置超時時間注意點
1、保證系統中只有一個RestTemplate的配置;不然可能與你的預期不一致。
2、永遠不要太相信自己寫的代碼;多打印日志才能真正知道調用時間;
1
2
3
4
5
6
7
|
long s = System.currentTimeMillis(); try { responseEntity = restTemplate.exchange(); } catch (Exception e) { long costTime = System.currentTimeMillis()-s; log.error( "調用**服務異常,花費時間:{},錯誤:{}" ,costTime, e.getMessage(), e); } |
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持服務器之家。
原文鏈接:https://www.cnblogs.com/dbave/p/9381097.html