Back to Java 11 Features
Q2Question 2 of 5

What is the Java 11 HttpClient?

Key Concepts
  • HttpClient.newHttpClient() creates a reusable, thread-safe client with connection pooling
  • send() is synchronous and blocks until the response arrives
  • sendAsync() returns CompletableFuture for non-blocking parallel calls
  • Built-in HTTP/2 support with automatic fallback to HTTP/1.1
  • Replaces HttpURLConnection which required manual stream handling and had no HTTP/2 or async support
  • Reuse a single HttpClient instance across the application for connection pooling

Definition

Java 11's HttpClient replaces HttpURLConnection with a modern builder API, HTTP/2 support, synchronous send() and asynchronous sendAsync() returning CompletableFuture.
  • HttpClient.newHttpClient() creates a default client. Use HttpClient.newBuilder() for custom configuration (timeouts, redirect policy, executor).
  • send(request, BodyHandlers.ofString()) is synchronous: blocks the calling thread until the response arrives.
  • sendAsync(request, BodyHandlers.ofString()) is asynchronous: returns CompletableFuture> immediately.
  • HTTP/2 is supported by default with automatic fallback to HTTP/1.1.
  • The client is immutable and thread-safe: designed to be created once and reused.
  • Replaces HttpURLConnection which required manual InputStream/OutputStream handling, had no HTTP/2, and no async support.

HttpURLConnection is like sending a bank letter by hand: open envelope, write address, stamp, wait at the post office. HttpClient is like the bank's digital messaging system: type message, click send-and-wait (sync) or click send-and-continue (async). It supports modern protocols (HTTP/2 for multiplexed connections) and connection reuse.

Understanding the Concepts

How do you make a synchronous GET request?

JAVA
package com.bank.gateway;

import java.net.URI;
import java.net.http.*;
import java.time.Duration;

public class HttpClientDemo {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newBuilder()
            .connectTimeout(Duration.ofSeconds(10))
            .build();

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://api.bank.example/accounts/SAV2001"))
            .header("Authorization", "Bearer token123")
            .GET()
            .build();

        // Synchronous: blocks until response
        HttpResponse<String> response = client.send(
            request, HttpResponse.BodyHandlers.ofString());

        System.out.println("Status: " + response.statusCode());
        System.out.println("Body: " + response.body());
    }
}

How do you make an asynchronous request?

JAVA
// Asynchronous: returns CompletableFuture immediately
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
    .thenApply(HttpResponse::body)
    .thenAccept(body -> System.out.println("Async body: " + body))
    .join();  // wait for completion in demo

How do you make a POST request?

JAVA
String json = "{\"holder\":\"Rajesh\",\"amount\":50000}";

HttpRequest postRequest = HttpRequest.newBuilder()
    .uri(URI.create("https://api.bank.example/transfers"))
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(json))
    .timeout(Duration.ofSeconds(30))
    .build();

HttpResponse<String> postResponse = client.send(
    postRequest, HttpResponse.BodyHandlers.ofString());

How is HttpClient better than HttpURLConnection?

| Feature | HttpURLConnection | HttpClient (Java 11) |
|---------|------------------|---------------------|
| API style | Verbose, manual streams | Clean builder pattern |
| HTTP/2 | Not supported | Built-in |
| Async | Not supported | sendAsync + CompletableFuture |
| Connection pooling | Manual | Automatic |
| Thread safety | Not reusable | Immutable, thread-safe |
| Body handling | Manual InputStream | Typed BodyHandlers |

What are common mistakes?

WRONG: Creating a new HttpClient per request.

JAVA
// WRONG: wasteful -- creates new client each time
HttpClient bad = HttpClient.newHttpClient();
HttpResponse<String> resp = bad.send(req, BodyHandlers.ofString());

CORRECT: Reuse a single client instance.

JAVA
// CORRECT: create once, reuse everywhere
private static final HttpClient CLIENT = HttpClient.newBuilder()
    .connectTimeout(Duration.ofSeconds(10))
    .build();

What should a senior engineer know?

  • HttpClient uses a shared executor (ForkJoinPool.commonPool) for async operations by default. For production, provide a custom executor via HttpClient.newBuilder().executor(myExecutor).
  • For Spring applications, WebClient or RestClient are typically used instead of raw HttpClient, but HttpClient is the standard library option with zero dependencies.
  • HttpClient supports WebSocket via HttpClient.newWebSocketBuilder().
  • The client handles redirects, authentication, and cookie management via builder configuration.

Visual Overview

DIAGRAM
  Synchronous (send):
  ┌──────────┐    request    ┌──────────┐
  │  Client  │──────────────→│  Server  │
  │ (blocks) │←──────────────│          │
  └──────────┘    response   └──────────┘

  Asynchronous (sendAsync):
  ┌──────────┐    request    ┌──────────┐
  │  Client  │──────────────→│  Server  │
  │ (returns │               │          │
  │  Future) │               │          │
  │  ...     │←──────────────│          │
  │ callback │    response   └──────────┘
  └──────────┘

Key Takeaway

Java 11's HttpClient replaces HttpURLConnection with a modern API: builder pattern for clients and requests, HTTP/2 support, synchronous send() that blocks and returns HttpResponse, and asynchronous sendAsync() that returns CompletableFuture. The client is immutable and thread-safe, designed to be created once and reused.

At National Bank of India, the payment gateway uses synchronous send() for single transfers and sendAsync() to fan out balance checks to multiple account services in parallel.

In interviews, mention the three key improvements: HTTP/2 support, async via CompletableFuture, and a clean builder API.

Remember one sentence: HttpClient is the modern, reusable, HTTP/2-capable replacement for HttpURLConnection with both sync and async modes.

---

Share
Use ← → arrow keys to navigate