Utilisation D'Apache HttpClient comment définir le délai d'attente sur une requête et une réponse

J'ai besoin de définir le délai pour la requête Http que nous faisons à un service (pas un service web). Nous utilisons le client HTTP Apache. J'ai ajouté ces 2 lignes de code pour définir le délai d'attente sur demande et réponse au service.

HttpConnectionParams.setConnectionTimeout(params, 10000);
HttpConnectionParams.setSoTimeout(params, 10000);

1) actuellement, j'ai défini 10 secondes comme délai d'attente puisque je vois la réponse provenant du service presque instantanément. Dois-je augmenter ou diminuer le calendrier?

2) Que se passera-t-il lorsque la réponse prend plus de 10 Secondes? Il throw exception et quelle exception sera-t-elle? Y at-il autre chose que je dois ajouter pour définir le temps dans le code ci-dessous.

public HashMap<String, Object> getJSONData(String url) throw Exception{
    DefaultHttpClient httpClient = new DefaultHttpClient();
    HttpParams params = httpClient.getParams();
    HttpConnectionParams.setConnectionTimeout(params, 10000);
    HttpConnectionParams.setSoTimeout(params, 10000);
    HttpHost proxy = new HttpHost(getProxy(), getProxyPort());
    ConnRouteParams.setDefaultProxy(params, proxy);
    URI uri;
    InputStream data = null;
    try {
        uri = new URI(url);
        HttpGet method = new HttpGet(uri);
        HttpResponse response = httpClient.execute(method);
        data = response.getEntity().getContent();
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    Reader r = new InputStreamReader(data);
    HashMap<String, Object> jsonObj = (HashMap<String, Object>) GenericJSONUtil.fromJson(r);
    return jsonObj;
}
29
demandé sur Nathan 2012-03-26 18:15:43

2 réponses

Les exceptions que vous verrez sera ConnectTimeoutException et SocketTimeoutException. Les valeurs de délai d'attente réelles que vous utilisez devraient être le temps maximum que votre application est prête à attendre. Une note importante sur le délai de lecture est qu'il correspond au délai d'attente sur une lecture de socket. Ce n'est donc pas le temps imparti pour que la réponse complète arrive, mais plutôt le temps donné à une seule lecture de socket. Donc, s'il y a 4 lectures de socket, chacune prenant 9 secondes, votre temps de lecture total est de 9 * 4 = 36 secondes.

Si vous voulez spécifiez une durée totale pour que la réponse arrive (y compris la connexion et le temps de lecture total), vous pouvez envelopper l'appel dans un thread et utiliser un délai d'attente de thread pour cela. Par exemple, je fais habituellement quelque chose comme ceci:

Future<T> future = null;
future = pool.submit(new Callable<T>() {
    public T call() {
        return executeImpl(url);
    }   
}); 

try {
    return future.get(10, TimeUnit.SECONDS);
}   
catch (InterruptedException e) {
    log.warn("task interrupted", name);
}   
catch (ExecutionException e) {
    log.error(name + " execution exception", e); 
}   
catch (TimeoutException e) {
    log.debug("future timed out", name);
}

Certaines hypothèses faites dans le code ci-dessus sont: 1) c'est dans une fonction avec un paramètre url, 2) c'est dans une classe avec une variable name, 3) log est une instance log4j, et 4) pool est un exécuteur de pool de threads. Notez que même si vous utilisez un fil délai d'attente, vous devez également spécifier un connect et socket timeout sur le HttpClient, de sorte que les requêtes lentes ne mangent pas les ressources dans le pool de threads. Notez également que j'utilise un pool de threads car généralement Je l'utilise dans un service web afin que le pool de threads soit partagé entre un tas de threads tomcat. Votre environnement peut être différent, et vous préférerez peut-être simplement générer un nouveau thread pour chaque appel.

En outre, j'ai l'habitude de voir les délais d'attente définis via les fonctions membres des paramètres, comme ceci:

params.setConnectionTimeout(10000);
params.setSoTimeout(10000);

Mais peut-être votre syntaxe fonctionne aussi bien (pas sûr).

31
répondu Kevin 2017-10-06 09:41:01

Je suppose que beaucoup de gens viennent ici à cause du titre et parce que l'API HttpConnectionParams est obsolète.

En utilisant une version récente du client HTTP Apache, vous pouvez définir ces délais d'attente à l'aide des paramètres de requête:

HttpPost request = new HttpPost(url);

RequestConfig requestConfig = RequestConfig.custom()
  .setSocketTimeout(TIMEOUT_MILLIS)
  .setConnectTimeout(TIMEOUT_MILLIS)
  .setConnectionRequestTimeout(TIMEOUT_MILLIS)
  .build();

request.setConfig(requestConfig);

Vous pouvez également définir cela lorsque vous créez votre client HTTP, en utilisant l'API builder pour le client HTTP, mais vous devrez également créer un gestionnaire de connexions personnalisé avec une configuration de socket personnalisée.

Le fichier d'exemple de configuration est un excellente ressource pour savoir comment configurer le client HTTP Apache.

54
répondu simao 2015-09-02 19:40:08