HttpClient în Java

Clientul HTTP din Java 11: newHttpClient() îl creează, send/sendAsync trimit cereri și primesc răspunsuri.

Sintaxă
import java.net.http.HttpClient;

static HttpClient newHttpClient()
static HttpClient.Builder newBuilder()

HttpClient client = HttpClient.newBuilder()
    .connectTimeout(Duration.ofSeconds(5))
    .followRedirects(HttpClient.Redirect.NORMAL)
    .build();

Ce face HttpClient

HttpClient (pachetul java.net.http) trimite cereri HTTP și HTTPS: GET, POST, PUT, DELETE. HttpClient.newHttpClient() creează un client cu setările implicite; HttpClient.newBuilder() permite setări: timp maxim de conectare, urmarea redirecționărilor, versiunea HTTP, proxy, autentificare.

Un client se creează o dată și se refolosește pentru toate cererile: păstrează conexiunile deschise și este sigur pentru mai multe fire. Din Java 21 este AutoCloseable, deci îl poți închide cu try-with-resources.

Lucrul cu el are trei piese: HttpRequest (ce trimiți), HttpClient.send sau sendAsync (trimiterea) și HttpResponse (ce primești). Exemplele de mai jos pornesc un mic server local cu HttpServer, ca să ruleze fără internet.

Ce returnează

Un HttpClient.

Exemple

Exemplul 1: Primul GET către un server local

import com.sun.net.httpserver.HttpServer;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;

public class Main {
    public static void main(String[] args) throws Exception {
        HttpServer server = HttpServer.create(new InetSocketAddress("127.0.0.1", 0), 0);
        server.createContext("/salut", schimb -> {
            byte[] corp = "Salut din Iași!".getBytes(StandardCharsets.UTF_8);
            schimb.sendResponseHeaders(200, corp.length);
            try (OutputStream out = schimb.getResponseBody()) {
                out.write(corp);
            }
        });
        server.start();
        URI adresa = URI.create("http://127.0.0.1:" + server.getAddress().getPort() + "/salut");

        try (HttpClient client = HttpClient.newHttpClient()) {
            HttpRequest cerere = HttpRequest.newBuilder(adresa).build();
            HttpResponse<String> raspuns = client.send(cerere, HttpResponse.BodyHandlers.ofString());
            System.out.println(raspuns.statusCode() + " " + raspuns.body());
        }
        server.stop(0);
    }
}

Rezultat

200 Salut din Iași!

Exemplul 2: Client configurat cu builder

import java.net.http.HttpClient;
import java.time.Duration;

public class Main {
    public static void main(String[] args) {
        try (HttpClient client = HttpClient.newBuilder()
                .connectTimeout(Duration.ofSeconds(5))
                .followRedirects(HttpClient.Redirect.NORMAL)
                .version(HttpClient.Version.HTTP_1_1)
                .build()) {
            System.out.println("Timp de conectare: " + client.connectTimeout().orElseThrow());
            System.out.println("Redirecționări: " + client.followRedirects());
            System.out.println("Versiune: " + client.version());
        }
    }
}

Rezultat

Timp de conectare: PT5S
Redirecționări: NORMAL
Versiune: HTTP_1_1

Exemplul 3: O cerere către un site real

Are nevoie de internet; codul de stare și antetele pot diferi.

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Main {
    public static void main(String[] args) throws Exception {
        try (HttpClient client = HttpClient.newHttpClient()) {
            HttpRequest cerere = HttpRequest.newBuilder(URI.create("https://dexblog.ro/")).build();
            HttpResponse<String> r = client.send(cerere, HttpResponse.BodyHandlers.ofString());
            System.out.println("Stare: " + r.statusCode());
            System.out.println("Tip: " + r.headers().firstValue("content-type").orElse("?"));
            System.out.println("Lungime pagină: " + r.body().length() + " caractere");
        }
    }
}

Rezultat posibil (necesită internet)

Stare: 200
Tip: text/html; charset=UTF-8
Lungime pagină: 48213 caractere

Greșeli frecvente

  • Creezi un HttpClient nou pentru fiecare cerere. Pierzi conexiunile refolosite; creează-l o dată.
  • Nu pui connectTimeout. Dacă serverul nu răspunde, conectarea poate aștepta foarte mult.

Comenzi înrudite

  • HttpClient.send: Trimite o cerere HTTP și așteaptă răspunsul; BodyHandlers.ofString() citește corpul ca text.
  • HttpClient.sendAsync: Trimite o cerere HTTP fără să aștepte: returnează imediat un CompletableFuture cu răspunsul.
  • HttpRequest: O cerere HTTP imutabilă (adresă, metodă, antete, corp), construită cu HttpRequest.newBuilder(uri)…build().
  • HttpResponse: Răspunsul la o cerere HTTP: statusCode() dă codul (200, 404…), body() corpul, headers() antetele.
  • URI: O adresă (URL) verificată și împărțită în părți; URI.create(„https://…”) o creează și aruncă IllegalArgumentException dacă e greșită.