skip to content

HTTP Client (java.net.http)

java.net.http gives you a modern client with synchronous send and asynchronous sendAsync returning a CompletableFuture, plus HTTP/2 and WebSocket support. It replaced HttpURLConnection, which is the comparison interviewers ask for.

part ofJavaoverview, primer and where to startread it →
on this pageshow

questions

5

What are the three core types in java.net.http, and how do they fit together to make an HTTP call?

level: juniorimportance: must knowfreq 70%

answer

  1. HttpClient = reusable engine + connection pool
  2. HttpRequest = one immutable call (uri/method/headers/body)
  3. HttpResponse<T> = statusCode/headers/body
  4. BodyPublisher sends body, BodyHandler shapes the reply
  5. newHttpClient() / newBuilder() / send()

basics

~10 s

You build an HttpClient once, create an HttpRequest describing the URL/method/headers, then call client.send(request, handler). The result is an HttpResponse holding the status code, headers, and body.

solid answer

~40 s

The API revolves around three immutable types. HttpClient is the long-lived, reusable, thread-safe object that holds configuration (HTTP version, redirect policy, connection pool, executor) — you build one and share it. HttpRequest describes a single call: URI, method, headers, and an optional body supplied by a BodyPublisher. HttpResponse<T> is the result, exposing statusCode(), headers(), and body() where T is whatever a BodyHandler produced (a String, byte[], Path, Stream<String>, etc.). The typical flow: HttpClient.newHttpClient(), then HttpRequest.newBuilder(uri).GET().build(), then client.send(request, BodyHandlers.ofString()). Builders make requests/clients immutable and safe to reuse. The handler is what turns raw response bytes into the typed body, so the same request can yield a String or be streamed to a file just by swapping the handler.

go deeper

for a junior

Can name the three types and write the basic GET-to-String flow, knowing the status code lives on the response.

for a middle

Explains immutability, the BodyPublisher vs BodyHandler split, and why the client is shared/thread-safe.

for a senior

Discusses connection pooling, HTTP/2 default, and that non-2xx is not an exception; reasons about handler choice (ofString vs ofFile vs streaming) for memory.

for a principal

Frames the API as a clean separation of configuration (client), intent (request), and delivery (handler), and weighs it against alternatives (OkHttp, WebClient) for a platform standard.

## What is HTTP and why this API exists HTTP (HyperText Transfer Protocol) is the request/response protocol the web runs on: a *client* sends a request (a method like GET, a URL, headers, optionally a body) to a *server*, which returns a *response* (a numeric status code such as 200, response headers, and a body). Before Java 11, the standard way to do this from Java was `HttpURLConnection`, a clunky 1990s API. `java.net.http` (incubated in Java 9, standardized in Java 11) is the modern replacement. ## The three core types **1. `HttpClient`** — the *engine*. It is configured once and reused for many requests. It holds: - the HTTP protocol version to prefer (HTTP/2 by default, falling back to HTTP/1.1), - a **connection pool** (reusable TCP/TLS connections so you don't pay handshake cost every call), - redirect policy, proxy, authenticator, and an `Executor` (thread pool) for async work. You create it with `HttpClient.newHttpClient()` (defaults) or `HttpClient.newBuilder()....build()`. It is **immutable and thread-safe**, so one instance should be shared across your application — creating a new client per request wastes the connection pool and threads. **2. `HttpRequest`** — a *value object* describing ONE call. Built via `HttpRequest.newBuilder()`: - `.uri(URI.create("https://..."))` — where to send it, - the method: `.GET()`, `.POST(bodyPublisher)`, `.PUT(...)`, `.DELETE()`, or `.method(name, publisher)`, - `.header(name, value)` / `.headers(...)` — request headers, - `.timeout(Duration)` — per-request timeout. A **`BodyPublisher`** supplies the request body for methods that have one (e.g. `BodyPublishers.ofString(json)`). `HttpRequest` is immutable once built. **3. `HttpResponse<T>`** — the *result*. Its type parameter `T` is the shape of the body you asked for. Key methods: - `statusCode()` → an `int` (200, 404, 500…), - `headers()` → an `HttpHeaders`, - `body()` → the typed body `T`, - `uri()` (final URI after redirects), `version()`. The `T` is decided by a **`BodyHandler<T>`** you pass to `send`. `BodyHandlers.ofString()` gives `HttpResponse<String>`; `BodyHandlers.ofByteArray()` gives `byte[]`; `BodyHandlers.ofFile(path)` streams straight to disk and gives `Path`. The handler decouples *what request you make* from *how you want the body delivered*. ## Putting it together ```java HttpClient client = HttpClient.newHttpClient(); // reuse this HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://api.example.com/data")) .GET() .build(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); int code = response.statusCode(); // e.g. 200 String body = response.body(); // the response text ``` ## Mental model Think of `HttpClient` as a *telephone* (set up once, dial many times), `HttpRequest` as the *message you want to send*, the `BodyHandler` as *how you want the reply written down*, and `HttpResponse` as *the reply itself*. The builder pattern and immutability mean each piece is safe to reuse and free of hidden mutable state.

  • Why is HttpClient meant to be shared rather than created per call?
    It owns a connection pool and an executor; reusing it lets TCP/TLS connections be kept alive and reused, avoiding repeated handshakes, and avoids spinning up redundant thread pools.
  • Does a 404 or 500 response cause send() to throw?
    No. Those are valid HTTP responses; send() returns normally and you inspect statusCode(). Exceptions are thrown for I/O failures, timeouts, or interruption — not for non-2xx statuses.

saying these in an interview costs you the question

  • Creating a new HttpClient per request (wastes the connection pool and threads)
  • Thinking HttpResponse exposes the body type without a BodyHandler
  • Confusing BodyPublisher (request body) with BodyHandler (response body)
  • Believing the client throws on a 404/500 — non-2xx statuses are normal responses, not exceptions

context

open as a page

What is the difference between HttpClient.send() and sendAsync(), and when would you use each?

level: middleimportance: must knowfreq 68%

basics

~10 s

send() is synchronous: it blocks the calling thread until the response arrives and returns the HttpResponse directly. sendAsync() is non-blocking: it returns immediately with a CompletableFuture that completes later with the response.

open as a page

Explain BodyPublishers and BodyHandlers: what each is for, and give examples of common ones.

level: middleimportance: should knowfreq 55%

basics

~20 s

A BodyPublisher supplies the request body you send (e.g. a string or file). A BodyHandler decides how the response body is delivered to you (e.g. as a String, byte array, or written to a file). They are opposite ends: outgoing vs incoming body.

open as a page

What out-of-the-box behaviors does the java.net.http client provide for HTTP/2, redirects, timeouts, and authentication?

level: seniorimportance: should knowfreq 48%

basics

~20 s

The client speaks HTTP/2 by default (falling back to HTTP/1.1), can follow redirects based on a configured policy, supports a connect timeout on the client and a per-request timeout, and can authenticate via a configured Authenticator or by adding an Authorization header yourself.

open as a page

Why was java.net.http introduced to replace HttpURLConnection, and what does it do better?

level: seniorimportance: nice to knowfreq 40%

basics

~10 s

HttpURLConnection is an old, awkward, blocking-only API with no HTTP/2 support. java.net.http replaces it with a modern, immutable builder-based client that supports HTTP/2, WebSocket, async calls via CompletableFuture, and pluggable request/response body handling.

open as a page