Весна RestTemplate ожидания
Я хотел бы установить время ожидания соединения для службы rest, используемой моим веб-приложением. Я использую Рестемплейт весны, чтобы поговорить со своей службой. Я провел некоторые исследования, и я нашел и использовал xml ниже (в моем приложении xml), который, как я считаю, предназначен для установки таймаута. Я использую Spring 3.0.
Я также видел ту же проблему здесь Настройка таймаута для spring webservices с RestTemplate но решения не кажутся такими чистыми , я бы предпочел установите значения таймаута через Spring config
<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 секунд и сообщает следующее исключение:
Орг.весенняя рамка.сеть.клиент.Ного ResourceAccessExcep: ошибка ввода/вывода: нет маршрута к хосту: подключить; вложенные исключением является Java.чистая.NoRouteToHostException: нет маршрута к хосту: соединения
Url неверный so 404, возвращенный службой rest: Ждет около 10 секунд и сообщает следующее исключение:
Орг.весенняя рамка.сеть.клиент.HttpClientErrorException: 404 Не Найден
Мои требования требуют более коротких тайм-аутов, поэтому я должен быть в состоянии изменить их. Есть идеи насчет того, что я делаю не так?
Большое спасибо.
5 ответов:
Для Пружинного Ботинка >= 1.4
@Configuration public class AppConfig { @Bean public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) { return restTemplateBuilder .setConnectTimeout(...) .setReadTimeout(...) .build(); } }
Для Пружинного Ботинка
@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
имеет открытые сеттерыconnectionRequestTimeout
,connectTimeout
, иreadTimeout
и@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); } }
Наконец-то у меня получилось.
Я думаю, что тот факт, что наш проект имел две разные версии jar commons-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
в своем коде и получаю значения таймаута из файла свойств.
Этот вопрос является первым звеном для поиска Spring Boot, поэтому было бы здорово поместить здесь Решение, рекомендованное в официальной документации . Spring Boot имеет свой собственный удобный боб RestTemplateBuilder:
@Bean public RestTemplate restTemplate( RestTemplateBuilder restTemplateBuilder) { return restTemplateBuilder .setConnectTimeout(500) .setReadTimeout(500) .build(); }
Ручное создание экземпляров RestTemplate является потенциально трудным подходом, поскольку другие автоматически настроенные бобы не вводятся в созданные вручную экземпляры.
Вот действительно простой способ установить тайм-аут:
RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory()); private ClientHttpRequestFactory getClientHttpRequestFactory() { int timeout = 5000; HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(); clientHttpRequestFactory.setConnectTimeout(timeout); return clientHttpRequestFactory; }
У меня был похожий сценарий,но также требовалось установить прокси. Самый простой способ, который я мог видеть, чтобы сделать это, состоял в том, чтобы расширить
SimpleClientHttpRequestFactory
Для простоты установки прокси (различные прокси для non-prod vs 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; }