web-dev-qa-db-fra.com

Java Requête client HTTP avec délai d'expiration défini

Je voudrais faire BIT (tests intégrés) à un certain nombre de serveurs dans mon nuage. J'ai besoin de la demande pour échouer sur un délai d'attente important.

Comment dois-je faire cela avec Java?

Essayer quelque chose comme ci-dessous ne semble pas fonctionner.

public class TestNodeAliveness {
 public static NodeStatus nodeBIT(String elasticIP) throws ClientProtocolException, IOException {
  HttpClient client = new DefaultHttpClient();
  client.getParams().setIntParameter("http.connection.timeout", 1);

  HttpUriRequest request = new HttpGet("http://192.168.20.43");
  HttpResponse response = client.execute(request);

  System.out.println(response.toString());
  return null;
 }


 public static void main(String[] args) throws ClientProtocolException, IOException {
  nodeBIT("");
 }
}

- EDIT: Clarifiez quelle bibliothèque est utilisée -

J'utilise httpclient d'Apache, voici la section appropriée de pom.xml

 <dependency>
   <groupId>org.Apache.httpcomponents</groupId>
   <artifactId>httpclient</artifactId>
   <version>4.0.1</version>
   <type>jar</type>
 </dependency>
83
Maxim Veksler
import org.Apache.http.client.HttpClient;
import org.Apache.http.impl.client.DefaultHttpClient;
import org.Apache.http.params.BasicHttpParams;
import org.Apache.http.params.HttpConnectionParams;
import org.Apache.http.params.HttpParams;

...

    // set the connection timeout value to 30 seconds (30000 milliseconds)
    final HttpParams httpParams = new BasicHttpParams();
    HttpConnectionParams.setConnectionTimeout(httpParams, 30000);
    client = new DefaultHttpClient(httpParams);
116
laz

Si vous utilisez Http Client version 4.3 ou supérieure, vous devriez utiliser ceci:

RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30 * 1000).build();
HttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();
108
Thunder

HttpParams est obsolète dans la nouvelle bibliothèque Apache HTTPClient. L'utilisation du code fourni par Laz entraîne des avertissements de dépréciation.

Je suggère d'utiliser RequestConfig à la place sur votre instance HttpGet ou HttpPost:

final RequestConfig params = RequestConfig.custom().setConnectTimeout(3000).setSocketTimeout(3000).build();
httpPost.setConfig(params);
31
pmartin8

Il semble que vous utilisiez l'API HttpClient, ce que je ne connais pas du tout, mais vous pouvez écrire quelque chose de similaire à l'aide de Java.

try {

   HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
   con.setRequestMethod("HEAD");
   con.setConnectTimeout(5000); //set timeout to 5 seconds
   return (con.getResponseCode() == HttpURLConnection.HTTP_OK);

} catch (Java.net.SocketTimeoutException e) {
   return false;
} catch (Java.io.IOException e) {
   return false;
}
10
dbyrne

J'ai trouvé que la définition des paramètres de délai d'attente dans HttpConnectionParams et HttpConnectionManager ne résolvait pas notre cas. Nous sommes limités à utiliser org.Apache.commons.httpclient Version 3.0.1.

J'ai fini par utiliser un Java.util.concurrent.ExecutorService Pour surveiller l'appel HttpClient.executeMethod().

Voici un petit exemple autonome

import org.Apache.commons.httpclient.HttpClient;
import org.Apache.commons.httpclient.methods.EntityEnclosingMethod;
import org.Apache.commons.httpclient.methods.PostMethod;
import org.Apache.commons.httpclient.methods.multipart.FilePart;
import org.Apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.Apache.commons.httpclient.methods.multipart.Part;
import Java.io.File;
import Java.io.IOException;
import Java.util.Arrays;
import Java.util.List;
import Java.util.concurrent.*;

/**
 * @author Jeff Kirby
 * @since <pre>Jun 17, 2011</pre>
 */
public class Example {

   private static final String SITE = "http://some.website.com/upload";
   private static final int TIME_OUT_SECS = 5;

   // upload a file and return the response as a string
   public String post(File file) throws IOException, InterruptedException {
      final Part[] multiPart = { new FilePart("file", file.getName(), file) };
      final EntityEnclosingMethod post = new PostMethod(SITE);
      post.setRequestEntity(new MultipartRequestEntity(multiPart, post.getParams()));
      final ExecutorService executor = Executors.newSingleThreadExecutor();
      final List<Future<Integer>> futures = executor.invokeAll(Arrays.asList(new KillableHttpClient(post)), TIME_OUT_SECS, TimeUnit.SECONDS);
      executor.shutdown();
      if(futures.get(0).isCancelled()) {
         throw new IOException(SITE + " has timed out. It has taken more than " + TIME_OUT_SECS + " seconds to respond");
      }
      return post.getResponseBodyAsString();
   }

   private static class KillableHttpClient implements Callable<Integer> {

      private final EntityEnclosingMethod post;

      private KillableHttpClient(EntityEnclosingMethod post) {
         this.post = post;
      }

      public Integer call() throws Exception {
         return new HttpClient().executeMethod(post);
      }
   }
}
7
Kirby

Ladite méthode avec les plus hautes valeurs par Laz est obsolète à partir de la version 4.3. Par conséquent, il serait préférable d’utiliser l’objet Request Config puis de construire le client HTTP.

    private CloseableHttpClient createHttpClient()
        {
        CloseableHttpClient httpClient;
        CommonHelperFunctions helperFunctions = new CommonHelperFunctions();
        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
        cm.setMaxTotal(306);
        cm.setDefaultMaxPerRoute(108);
        RequestConfig requestConfig = RequestConfig.custom()
            .setConnectTimeout(15000)
            .setSocketTimeout(15000).build();
        httpClient = HttpClients.custom()
            .setConnectionManager(cm)
            .setDefaultRequestConfig(requestConfig).build();
        return httpClient;
        }

Le PoolingHttpClientConnectionManager est l’utilisateur qui définit le nombre maximal de connexions par défaut et le nombre maximal de connexions par route. Je l'ai mis à 306 et 108 respectivement. Les valeurs par défaut ne seront pas suffisantes dans la plupart des cas.

Pour définir Timeout: J'ai utilisé l'objet RequestConfig. Vous pouvez également définir la propriété Délai de demande de connexion pour définir le délai d'attente de la connexion depuis le gestionnaire de connexion.

Cela a déjà été mentionné dans un commentaire de benvoliot ci-dessus. Mais, je pense que ça vaut le coup d’être un poste de haut niveau, car c’était sûr que je me suis gratifié la tête. Je poste ceci au cas où cela aiderait quelqu'un d'autre.

J'ai écrit un client test simple et le CoreConnectionPNames.CONNECTION_TIMEOUT timeout fonctionne parfaitement dans ce cas. La demande est annulée si le serveur ne répond pas.

À l'intérieur du code du serveur, j'essayais en fait de tester, cependant, le code identique n'expire jamais.

Le changer pour expirer sur l'activité de la connexion socket (CoreConnectionPNames.SO_TIMEOUT) plutôt que la connexion HTTP (CoreConnectionPNames.CONNECTION_TIMEOUT) résolu le problème pour moi.

Lisez également attentivement la documentation Apache: http://hc.Apache.org/httpcomponents-core-ga/httpcore/apidocs/org/Apache/http/params/CoreConnectionPNames.html#CONNECTION_TIMEOUT

Notez le bit qui dit

Veuillez noter que ce paramètre ne peut être appliqué qu'aux connexions liées à une adresse locale particulière.

J'espère que cela évitera à quelqu'un d'autre toute la tête que j'ai traversée. Cela m'apprendra à ne pas lire la documentation à fond!

5
Dan Haynes

Plus tard, Op a déclaré qu'ils utilisaient Apache Commons HttpClient 3.0.1

 HttpClient client = new HttpClient();
        client.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
        client.getHttpConnectionManager().getParams().setSoTimeout(5000);
2
rtaft

HttpConnectionParams.setSoTimeout(params, 10*60*1000);// for 10 mins i have set the timeout

Vous pouvez également définir votre temps de pause requis.