• Home
  • About
    • Thoughts To Pen photo

      Thoughts To Pen

      My thoughts on Computer Programming || Psychology || Personal Finances || & much more...

    • Learn More
    • Twitter
    • Instagram
    • Github
    • StackOverflow
  • Posts
    • All Posts
    • All Tags
  • Projects
  • Portfolio
  • Resources
  • About

Standard HTTP Client API (Java 11)

02 Dec 2025

For nearly two decades, Java developers relied on HttpURLConnection for network requests. While functional, it was designed in an era before HTTP/2, WebSockets, and non-blocking I/O, leading to clunky and hard-to-maintain code. Java 11 changed everything by introducing a modern HTTP Client API.

What is the Java 11 HTTP Client?

The new HttpClient (JEP 321) is a modern replacement for legacy networking APIs. It resides in the java.net.http module and provides a fluent, builder-based API for creating requests and handling responses either synchronously or asynchronously.

Key pillars of this API:

  1. HttpClient: The engine that sends requests.
  2. HttpRequest: The builder for your request (URL, headers, method).
  3. HttpResponse: The object holding the results (status code, body).

Sending a Simple Synchronous Request

If you just need to fetch data and wait for it, a synchronous request is the easiest way to start.

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

public class SyncRequestExample {
    public static void main(String[] args) throws Exception {
        // 1. Create a client
        HttpClient client = HttpClient.newHttpClient();

        // 2. Build the request
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://jsonplaceholder.typicode.com/posts/1"))
                .GET()
                .build();

        // 3. Send and get response
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

        // 4. Print results
        System.out.println("Status Code: " + response.statusCode());
        System.out.println("Response Body: " + response.body());
    }
}

Going Asynchronous (Non-Blocking)

One of the biggest advantages of the new API is its native support for asynchronous requests. Instead of blocking your main thread, you can use CompletableFuture to handle the response whenever it arrives.

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.CompletableFuture;

public class AsyncRequestExample {
    public static void main(String[] args) {
        HttpClient client = HttpClient.newHttpClient();

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://jsonplaceholder.typicode.com/posts/2"))
                .build();

        // Send asynchronously
        CompletableFuture<HttpResponse<String>> future = client.sendAsync(request, HttpResponse.BodyHandlers.ofString());

        // Attach callbacks
        future.thenApply(HttpResponse::body)
              .thenAccept(body -> System.out.println("Received: " + body))
              .join(); // Only for demo purposes to prevent program exit
    }
}

Support for HTTP/2

The new client supports both HTTP/1.1 and HTTP/2. By default, it prefers HTTP/2 if the server supports it, automatically falling back to HTTP/1.1 if necessary.

HttpClient client = HttpClient.newBuilder()
    .version(HttpClient.Version.HTTP_2)
    .build();

Real-World Example: Fetching Weather Data

Let’s imagine you are building a simple weather app. You need to send a custom header and handle potential errors.

public void fetchWeather(String city) {
    HttpClient client = HttpClient.newBuilder()
            .followRedirects(HttpClient.Redirect.NORMAL)
            .build();

    HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://api.weather.com?city=" + city))
            .header("Accept", "application/json")
            .timeout(Duration.ofSeconds(10))
            .build();

    client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
          .thenApply(response -> {
              if (response.statusCode() == 200) {
                  return response.body();
              } else {
                  return "Error: " + response.statusCode();
              }
          })
          .thenAccept(System.out::println)
          .exceptionally(ex -> {
              System.err.println("API Call Failed: " + ex.getMessage());
              return null;
          });
}

Conclusion

The Java 11 HTTP Client API is a breath of fresh air for Java developers. It is powerful, readable, and perfectly suited for modern microservices and reactive applications. By supporting HTTP/2 and providing a clean asynchronous model, it makes HttpURLConnection and third-party libraries less of a necessity for standard tasks.



programmingjavajava11 Share Tweet Msg