Тайм-аут RestTemplate весны
Я хотел бы установить таймауты соединения для службы rest, используемой моим веб-приложением. Я использую RestTemplate весны, чтобы поговорить с моей службой. Я провел некоторое исследование, и я нашел и использовал xml ниже (в моем приложении xml), который, я считаю, предназначен для установки тайм-аута. Я использую Spring 3.0.
Я также видел ту же проблему здесь конфигурация тайм-аута для весенних веб-сервисов с 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 секунд и сообщает следующее исключение:
org.springframework.сеть.клиент.Resourceaccessexception: ошибка ввода-вывода: нет маршрута к хосту: connect; вложенное исключение-java.сеть.NoRouteToHostException: нет маршрута к хосту: connect
Url неверный, поэтому 404 возвращается службой rest: Ждет около 10 секунд и сообщает следующее исключение:
org.springframework.сеть.клиент.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);
}
}
я, наконец, получил это работает.
Я думаю, что тот факт, что наш проект имел две разные версии commons-httpclient jar, не помогал. Как только я разобрался с этим, я обнаружил, что ты можешь делать две вещи...
в коде вы можете поставить следующее:
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 имеет свой собственный удобство bean 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;
}