Client HTTP en Java : effectuer des requêtes correctement (niveau avancé)
Travailler avec des requêtes HTTP est l'une des tâches fondamentales du développement Java moderne. Cependant, écrire un code qui non seulement envoie une requête, mais le fait de manière fiable, avec une gestion correcte des erreurs, des délais d'attente et des ressources, nécessite une compréhension approfondie. Dans cet article, nous dépasserons le simple HttpURLConnection et explorerons les techniques avancées de travail avec les clients HTTP en Java, en utilisant le java.net.http.HttpClient intégré (Java 11+) et la bibliothèque populaire OkHttp.
1. Gestion des délais d'attente : ne laissez pas votre application se bloquer
L'un des problèmes les plus courants lors du travail avec HTTP est le blocage de l'application dû à un serveur lent ou inaccessible. Une configuration correcte des délais d'attente est la première étape vers la création d'un client tolérant aux pannes.
Types de délais d'attente :
- Connect Timeout : Temps d'attente pour l'établissement de la connexion TCP avec le serveur.
- Read Timeout (Socket Timeout) : Temps d'attente des données du serveur après l'établissement de la connexion.
- Write Timeout : Temps d'attente pour l'envoi des données au serveur (pertinent pour POST/PUT).
- Request Timeout : Temps total d'exécution de l'ensemble de la requête HTTP (incluant la connexion, l'envoi et la réception de la réponse).
Exemple de configuration pour java.net.http.HttpClient :
import java.net.http.HttpClient;import java.time.Duration;
public class TimeoutExample { public static HttpClient createClientWithTimeouts() { return HttpClient.newBuilder() .connectTimeout(Duration.ofSeconds(5)) // Délai d'attente de connexion .build(); }
public static void main(String[] args) { HttpClient client = createClientWithTimeouts(); // Pour les délais d'attente Read/Write, nous utilisons HttpRequest var request = java.net.http.HttpRequest.newBuilder() .uri(java.net.URI.create("https://api.example.com/data")) .timeout(Duration.ofSeconds(10)) // Délai d'attente total pour la requête .GET() .build(); System.out.println("Client avec délais d'attente créé : " + client); }}Exemple de configuration pour OkHttp :
import okhttp3.OkHttpClient;import java.util.concurrent.TimeUnit;
public class OkHttpTimeoutExample { public static OkHttpClient createOkHttpClient() { return new OkHttpClient.Builder() .connectTimeout(5, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS) .writeTimeout(10, TimeUnit.SECONDS) .callTimeout(30, TimeUnit.SECONDS) // Délai d'attente total pour l'appel .build(); }
public static void main(String[] args) { OkHttpClient client = createOkHttpClient(); System.out.println("Client OkHttp avec délais d'attente prêt à fonctionner."); }}2. Pool de connexions et réutilisation : économiser les ressources
Chaque nouvelle connexion HTTP nécessite des ressources pour établir la poignée de main TCP et, éventuellement, la poignée de main TLS. Pour les applications qui effectuent de nombreuses requêtes vers un même serveur, il est essentiel d'utiliser un pool de connexions (connection pool). Cela permet de réutiliser les connexions existantes, ce qui accélère considérablement les requêtes et réduit la charge réseau.
java.net.http.HttpClient dispose d'un pool de connexions intégré, géré automatiquement. Cependant, vous pouvez configurer sa taille :
import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;import java.net.URI;import java.time.Duration;
public class PoolExample { public static void main(String[] args) throws Exception { // HttpClient gère lui-même le pool, mais nous pouvons limiter