Printemps RestTemplate temps d'arrêt

je voudrais régler les temps morts de connexion pour un service de repos utilisé par mon application web. J'utilise le RestTemplate de Spring pour parler à mon service. J'ai fait quelques recherches et j'ai trouvé et utilisé le xml ci-dessous (dans mon application xml) qui je crois est destiné à définir le délai. Je suis à l'aide de Spring 3.0.

j'ai également vu le même problème ici la configuration de temporisation pour les serveurs Web de printemps avec RestTemplate mais les solutions ne semblent pas que clean , je préfère régler les valeurs de timeout via 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>

il semble que quel que soit le temps de lecture que j'ai mis, j'obtiens ce qui suit:

câble réseau déconnecté: Attend environ 20 secondes et signale l'exception suivante:

org.springframework.Web.client.Resourceaccessexception: I / O error: No route to host: connect; nested exception is java.net.NoRouteToHostException: No route to host: connect

Url incorrect de sorte 404 retourné par le service de repos: Attend environ 10 secondes et signale l'exception suivante:

org.springframework.Web.client.Httpclientrorexception: 404 Not Found

mes exigences nécessitent des délais d'attente plus courts, donc je dois pouvoir les modifier. Toutes les idées de ce que je fais mal?

Beaucoup de grâce.

75
demandé sur Community 2012-12-12 13:50:07

5 réponses

Pour Bottes À Ressort > = 1,4

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

Pour Printemps De Démarrage <= 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 parce que HttpComponentsClientHttpRequestFactory a des setters publics connectionRequestTimeout , connectTimeout , et readTimeout et @ConfigurationProperties les fixe pour vous.


Pour ressort 4.1 ou ressort 5 sans botte de ressort utilisant @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);
    }
}
97
répondu dustin.schultz 2018-08-23 03:36:05

j'ai enfin réussi.

je pense que le fait que notre projet ait eu deux versions différentes de la jarre commons-httpclient n'a pas aidé. Une fois que j'ai réglé ça, j'ai découvert que tu pouvais faire deux choses...

dans le code vous pouvez mettre ce qui suit:

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

la première fois que ce code est appelé il va définir le délai pour la classe HttpComponentsClientHttpRequestFactory utilisé par le RestTemplate . Par conséquent, tous les appels subséquents faits par RestTemplate utilisera les réglages de temporisation définis ci-dessus.

Ou la meilleure option est de faire ceci:

<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>

où j'utilise l'interface RestOperations dans mon code et j'obtiens les valeurs de timeout à partir d'un fichier de propriétés.

62
répondu sardo 2013-10-27 17:43:22

cette question Est le premier lien pour une recherche de Botte de printemps, donc, serait grand de mettre ici la solution recommandé dans la documentation officielle . 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 parce que d'autres fèves auto-configurées ne sont pas injectées dans des instances créées manuellement.

13
répondu heldev 2018-09-10 23:06:00

Voici une façon très simple de régler le délai:

RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());

private ClientHttpRequestFactory getClientHttpRequestFactory() {
    int timeout = 5000;
    HttpComponentsClientHttpRequestFactory clientHttpRequestFactory =
      new HttpComponentsClientHttpRequestFactory();
    clientHttpRequestFactory.setConnectTimeout(timeout);
    return clientHttpRequestFactory;
}
12
répondu benscabbia 2016-08-15 05:47:10

j'ai eu un scénario similaire, mais j'ai aussi été obligé de définir un Proxy. La façon la plus simple que j'ai pu voir pour faire cela était d'étendre le SimpleClientHttpRequestFactory pour la facilité de définir le proxy (différents proxies pour non-prod vs prod). Cela devrait fonctionner même si vous n'avez pas besoin du proxy. Puis, dans ma classe étendue, j'outrepasse la méthode openConnection(URL url, Proxy proxy) , en utilisant la même méthode que la" source , mais en réglant simplement les temps morts avant de revenir.

@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;
}
0
répondu Ryan D 2017-10-04 15:10:10