HTTP client for Java: overview of top libraries
In modern Java development, almost no application can do without interaction via the HTTP protocol. Sending requests to REST APIs, downloading files, working with microservices — all of this requires a reliable and convenient HTTP client. In this article, we will look at four of the most popular libraries for working with HTTP in Java: the standard HttpClient (Java 11+), Apache HttpClient, OkHttp, and Retrofit. You will learn their features, strengths, and get practical code examples.
1. Java 11 HttpClient (java.net.http)
Starting with Java 11, a modern HTTP client was added to the standard library, designed to replace the outdated HttpURLConnection. It supports HTTP/2, WebSocket, asynchronous requests, and reactive streams.
Advantages:
- No additional dependencies required — built into the JDK.
- Support for HTTP/2 and automatic protocol upgrade.
- Convenient API with synchronous and asynchronous calls.
- Built-in support for cookie handling, redirects, and authentication.
Example of a synchronous GET request:
import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;
public class Java11HttpClientExample { public static void main(String[] args) throws Exception { HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://jsonplaceholder.typicode.com/posts/1")) .GET() .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println("Status code: " + response.statusCode()); System.out.println("Body: " + response.body()); }}Example of an asynchronous POST request:
import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;import java.net.http.HttpRequest.BodyPublishers;import java.util.concurrent.CompletableFuture;
public class AsyncPostExample { public static void main(String[] args) { HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://jsonplaceholder.typicode.com/posts")) .header("Content-Type", "application/json") .POST(BodyPublishers.ofString("{\\"title\\":\\"foo\\",\\"body\\":\\"bar\\",\\"userId\\":1}")) .build();
CompletableFuture<HttpResponse<String>> future = client.sendAsync(request, HttpResponse.BodyHandlers.ofString()); future.thenAccept(response -> { System.out.println("Status: " + response.statusCode()); System.out.println("Body: " + response.body()); }).join(); }}2. Apache HttpClient
A classic library from Apache, which for a long time was the de facto standard. The latest version (5.x) has received significant improvements: support for HTTP/2, improved connection pool handling, and more flexible configuration.
Advantages:
- Maximum flexibility and fine-tuning (timeouts, interceptors, caching).
- Proven stability over time.
- Support for various authentication schemes (Basic, Digest, NTLM).
- Good integration with proxies and SSL.
Example of a GET request with Apache HttpClient 5:
import org.apache.hc.client5.http.classic.methods.HttpGet;import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;import org.apache.hc.client5.http.impl.classic.Clos