Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Java reference

HttpClient

The built-in HTTP client: sends requests synchronously (send) or asynchronously (sendAsync).

Available since: Java 11

Syntax

public abstract class HttpClient implements AutoCloseable

Examples

A GET request. So that the example works offline, it first starts a tiny local server; in real code use an address like https://... instead of uri:

import com.sun.net.httpserver.HttpServer;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.http.*;
 
void main() throws Exception {
    // a tiny local server so the example runs offline
    HttpServer server = HttpServer.create(new InetSocketAddress("localhost", 0), 0);
    server.createContext("/hello", exchange -> {
        byte[] body = "Hello from server".getBytes();
        exchange.sendResponseHeaders(200, body.length);
        exchange.getResponseBody().write(body);
        exchange.close();
    });
    server.start();
    URI uri = URI.create("http://localhost:" + server.getAddress().getPort() + "/hello");
 
    try (HttpClient client = HttpClient.newHttpClient()) {
        HttpRequest request = HttpRequest.newBuilder(uri).build();
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        IO.println(response.statusCode());
        IO.println(response.body());
    }
    server.stop(0);
}

Output:

200
Hello from server

Configuring the client with newBuilder() and an asynchronous request: sendAsync() returns a CompletableFuture right away:

import com.sun.net.httpserver.HttpServer;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.http.*;
 
void main() throws Exception {
    HttpServer server = HttpServer.create(new InetSocketAddress("localhost", 0), 0);
    server.createContext("/time", exchange -> {
        byte[] body = "12:00".getBytes();
        exchange.sendResponseHeaders(200, body.length);
        exchange.getResponseBody().write(body);
        exchange.close();
    });
    server.start();
    URI uri = URI.create("http://localhost:" + server.getAddress().getPort() + "/time");
 
    try (HttpClient client = HttpClient.newBuilder()
            .connectTimeout(Duration.ofSeconds(5))
            .followRedirects(HttpClient.Redirect.NORMAL)
            .build()) {
        CompletableFuture<String> body = client
            .sendAsync(HttpRequest.newBuilder(uri).build(), HttpResponse.BodyHandlers.ofString())
            .thenApply(HttpResponse::body);
        IO.println("Request sent");
        IO.println("Server time: " + body.join());
    }
    server.stop(0);
}

Output:

Request sent
Server time: 12:00

Notes

The client lives in the java.net.http module, so a compact source file needs import java.net.http.*;. Create one client and reuse it for all requests: it is thread-safe and keeps a connection pool. Since Java 21 the client can be closed with try with resources. send() throws IOException (no connection) and InterruptedException; a 404 or 500 response is not an exception — check statusCode(). The built-in server com.sun.net.httpserver.HttpServer is fine for examples and tests.

See also

  • HttpRequest — An immutable HTTP request: address, method, headers and body. Created with newBuilder().
  • HttpResponse — The server response: the status code, headers and a body of the type chosen by the BodyHandler.
  • CompletableFuture.thenApply() — Adds a step that transforms the result once it is ready.
  • try-with-resources — A `try` block that closes opened resources automatically — files, connections, streams.

In the tutorial

  • HTTP client — Making requests to web servers from Java — HttpClient, HttpRequest and HttpResponse.BodyHandlers, GET and POST with JSON, status codes and asynchronous sendAsync.

Thanks for reading!

Donate to the site — we work hard for you.