Communication HTTP en Java : Requêtes Synchrones et Asynchrones

En Java, l'envoi de requêtes HTTP peut être effectué de manière synchrone ou asynchrone. La bibliothèque Apache HttpClient offre des solutions pour les deux approches.

Requêtes HTTP Synchrones

Pour les requêtes synchrones, l'utilisation de la classe CloseableHttpClient est courante.


import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.http.client.methods.CloseableHttpResponse;

import java.io.IOException;

public class SynchronousRequest {

   public void executeSynchronousRequest(String targetUrl) throws IOException {
       try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
           HttpGet httpRequest = new HttpGet(targetUrl);
           
           try (CloseableHttpResponse response = httpClient.execute(httpRequest)) {
               int statusCode = response.getStatusLine().getStatusCode();
               System.out.println("Statut de la réponse : " + statusCode);
               
               String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
               System.out.println("Contenu de la réponse : " + responseBody);
           }
       }
   }

   // Exemple d'utilisation :
   // public static void main(String[] args) {
   //     SynchronousRequest requester = new SynchronousRequest();
   //     try {
   //         requester.executeSynchronousRequest("http://example.com/api/data");
   //     } catch (IOException e) {
   //         e.printStackTrace();
   //     }
   // }
}
   

Requêtes HTTP Asynchrones

Pour les requêtes asynchrones, qui permettent à votre application de continuer son exécution sans attendre la réponse, HttpAsyncClient est l'outil approprié.


import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class AsynchronousRequest {

   public void executeAsynchronousRequest(String targetUrl) throws InterruptedException {
       CloseableHttpAsyncClient asyncClient = HttpAsyncClients.createDefault();
       asyncClient.start();

       CountDownLatch completionBarrier = new CountDownLatch(1);
       HttpGet request = new HttpGet(targetUrl);

       System.out.println("Thread appelant : " + Thread.currentThread().getId());

       asyncClient.execute(request, new FutureCallback<HttpResponse>() {
           @Override
           public void completed(final HttpResponse result) {
               completionBarrier.countDown();
               System.out.println("Thread de rappel : " + Thread.currentThread().getId());
               System.out.println(request.getRequestLine() + " --> " + result.getStatusLine());
               try {
                   String responseContent = EntityUtils.toString(result.getEntity(), "UTF-8");
                   System.out.println("Contenu reçu : " + responseContent);
               } catch (IOException e) {
                   System.err.println("Erreur lors de la lecture de l'entité : " + e.getMessage());
               }
           }

           @Override
           public void failed(final Exception ex) {
               completionBarrier.countDown();
               System.out.println("Thread de rappel : " + Thread.currentThread().getId());
               System.out.println(request.getRequestLine() + " --> " + ex);
           }

           @Override
           public void cancelled() {
               completionBarrier.countDown();
               System.out.println("Thread de rappel : " + Thread.currentThread().getId());
               System.out.println(request.getRequestLine() + " annulé");
           }
       });

       // Attendre la fin de l'opération asynchrone
       completionBarrier.await(30, TimeUnit.SECONDS); // Ajout d'un timeout pour éviter un blocage infini

       try {
           asyncClient.close();
       } catch (IOException ignored) {
           // Ignorer l'exception lors de la fermeture
       }
   }

   // Exemple d'utilisation :
   // public static void main(String[] args) {
   //     AsynchronousRequest asyncRequester = new AsynchronousRequest();
   //     try {
   //         asyncRequester.executeAsynchronousRequest("https://www.google.com");
   //     } catch (InterruptedException e) {
   //         e.printStackTrace();
   //     }
   // }
}
   

Gestion des Timeouts avec HttpClient

Il est crucial de configurer des timeoust pour éviter que les requêtes ne bloquent indéfiniment votre application. Les principaux paramètres de timeout dans HttpClient sont :

  • ConnManagerParams.setTimeout(params, 1000) : Délai d'attente pour obtenir une connexion depuis le pool de connexions. En cas d'échec, une ConnectionPoolTimeoutException est levée.
  • HttpConnectionParams.setConnectionTimeout(params, 2000) : Délai d'attente pour établir la connexion réseau avec le serveur. Une tentative de connexion socket est effectuée en arrière-plan. En cas d'échec, une ConnectionTimeoutException est levée.
  • HttpConnectionParams.setSoTimeout(params, 4000) : Délai d'attente pour recevoir des données du socket une fois la connexion établie. En cas d'échec de lecture ou de réception, une SocketTimeoutException est levée.

En-têtes HTTP Courants

Lors de l'envoi de requêtes HTTP, certains en-têtes sont fréquemment utilisés :

  • Accept : Indique les types de médias que le client est prêt à acepter en réponse (ex: application/json, text/html, */* pour tous les types).
  • Connection : Gère la gestion de la connexion. Les valeurs courantes sont keep-alive (maintient la connexion ouverte pour des requêtes ultérieures) et close (ferme la connexion après la réponse).
  • User-Agent : Identifie le client (navigateur ou application) qui envoie la requête.

Étiquettes: Java HttpClient requête synchrone requête asynchrone httpasyncclient

Publié le 15 juillet à 11h57