Spring RestTemplate timeout

Je voudrais définir les délais de connexion pour un service de repos utilisé par mon application Web. J’utilise Spring’s RestTemplate pour parler à mon service. J’ai fait des recherches et j’ai trouvé et utilisé le xml ci-dessous (dans mon application xml) qui, je pense, est destiné à définir le délai d’attente. J’utilise Spring 3.0.

J’ai aussi vu le même problème ici Configuration de timeout pour les webservices Spring avec RestTemplate mais les solutions ne semblent pas aussi propres , je préférerais définir les valeurs de timeout via la configuration de Spring

       

Il semble que ce que je mets au readTimeout soit:

Câble réseau déconnecté: attend environ 20 secondes et signale les exceptions suivantes:

org.springframework.web.client.ResourceAccessException: Erreur d’E / S: aucune route à héberger: connect; l’exception nestede est java.net.NoRouteToHostException: aucune route à héberger: connect

Url incorrect donc 404 retourné par le service de repos: attend environ 10 secondes et signale l’exception suivante:

org.springframework.web.client.HttpClientErrorException: 404 introuvable

Mes exigences nécessitent des délais d’attente plus courts. Je dois donc pouvoir les modifier. Des idées sur ce que je fais mal?

Merci beaucoup.

Pour Spring Boot> = 1.4

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

Pour Spring Boot <= 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()); } } 

puis dans votre application.properties

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

Cela fonctionne car HttpComponentsClientHttpRequestFactory a des HttpComponentsClientHttpRequestFactory publics connectionRequestTimeout , readTimeout et @ConfigurationProperties et @ConfigurationProperties définit pour vous.


Pour Spring 4.1 ou Spring 5 sans Spring Boot à l’ aide de @Configuration au lieu de XML

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

J’ai finalement obtenu ce travail.

Je pense que le fait que notre projet ait eu deux versions différentes du pot commun-httpclient n’a pas aidé. Une fois que j’ai réglé cela, j’ai trouvé que vous pouviez faire deux choses …

Dans le code, vous pouvez mettre les éléments suivants:

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

La première fois que ce code est appelé, il définit le délai d’expiration de la classe HttpComponentsClientHttpRequestFactory utilisée par RestTemplate . Par conséquent, tous les appels ultérieurs effectués par RestTemplate utiliseront les parameters de délai d’attente définis ci-dessus.

Ou la meilleure option est de faire ceci:

         

Où j’utilise l’interface RestOperations dans mon code et j’obtiens les valeurs de délai d’attente à partir d’un fichier de propriétés.

Voici un moyen très simple de définir le délai d’attente:

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

Cette question est le premier lien pour une recherche Spring Boot, par conséquent, serait bien de mettre ici la solution recommandée dans la documentation officielle . Spring Boot a son propre bean comfort RestTemplateBuilder :

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

La création manuelle d’instances RestTemplate est une approche potentiellement problématique car d’autres beans auto-configurés ne sont pas injectés dans des instances créées manuellement.

J’avais un scénario similaire, mais je devais également définir un proxy. Le moyen le plus simple de le faire était d’étendre le SimpleClientHttpRequestFactory pour faciliter la définition du proxy (différents proxys pour non-prod vs prod). Cela devrait toujours fonctionner même si vous n’avez pas besoin du proxy. Ensuite, dans ma classe étendue, je remplace la openConnection(URL url, Proxy proxy) , en utilisant le même que la source , mais en définissant simplement les délais avant le retour.

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