Java HTTP Client: Advanced Request Handling Techniques

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Java HTTP Client: Making Requests Properly (Advanced Level)



Working with HTTP requests is one of the fundamental tasks in modern Java development. However, writing code that not only sends a request but does so reliably, with proper error handling, timeouts, and resource management, requires a deep understanding. In this article, we will go beyond simple HttpURLConnection and explore advanced techniques for working with HTTP clients in Java, using the built-in java.net.http.HttpClient (Java 11+) and the popular OkHttp library.



1. Managing Timeouts: Don't Let Your Application Hang



One of the most common problems when working with HTTP is an application hanging due to a slow or unavailable server. Properly configuring timeouts is the first step toward building a fault-tolerant client.



Types of Timeouts:

  • Connect Timeout: The time to wait for establishing a TCP connection with the server.
  • Read Timeout (Socket Timeout): The time to wait for data from the server after the connection is established.
  • Write Timeout: The time to wait for sending data to the server (relevant for POST/PUT).
  • Request Timeout: The total time for the entire HTTP request (including connection, sending, and receiving the response).


Configuration example for java.net.http.HttpClient:

import java.net.http.HttpClient;import java.time.Duration;

public class TimeoutExample { public static HttpClient createClientWithTimeouts() { return HttpClient.newBuilder() .connectTimeout(Duration.ofSeconds(5)) // Connection timeout .build(); }

public static void main(String[] args) { HttpClient client = createClientWithTimeouts(); // For Read/Write timeouts, use HttpRequest var request = java.net.http.HttpRequest.newBuilder() .uri(java.net.URI.create("https://api.example.com/data")) .timeout(Duration.ofSeconds(10)) // Total request timeout .GET() .build(); System.out.println("Client with timeouts created: " + client); }}


Configuration example for OkHttp:

import okhttp3.OkHttpClient;import java.util.concurrent.TimeUnit;

public class OkHttpTimeoutExample { public static OkHttpClient createOkHttpClient() { return new OkHttpClient.Builder() .connectTimeout(5, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS) .writeTimeout(10, TimeUnit.SECONDS) .callTimeout(30, TimeUnit.SECONDS) // Total timeout for the entire call .build(); }

public static void main(String[] args) { OkHttpClient client = createOkHttpClient(); System.out.println("OkHttp client with timeouts is ready to work."); }}


2. Connection Pooling and Reuse: Saving Resources



Each new HTTP connection requires overhead for establishing a TCP handshake and, possibly, a TLS handshake. For applications that make many requests to the same server, it is critical to use a connection pool. This allows reusing existing connections, significantly speeding up requests and reducing network load.



java.net.http.HttpClient has a built-in connection pool that is managed automatically. However, you can configure its size:

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

public class PoolExample { public static void main(String[] args) throws Exception { // HttpClient manages the pool itself, but we can limit

Blogs

Book Recommendations