Of course! Working with HTTP headers is a fundamental task in Java, especially when building web clients or servers. The primary tool for this in modern Java is the Java HTTP Client, introduced in Java 11 as part of the java.net.http package.

Here's a comprehensive guide covering:
- The Modern Way (Java 11+): Using the built-in
HttpClient. - The Classic Way (Legacy): Using
HttpURLConnection. - Popular Third-Party Libraries: Apache HttpClient and OkHttp.
- Common HTTP Headers and Examples.
The Modern Way: java.net.http.HttpClient (Java 11+)
This is the recommended approach for new projects. It's a modern, fluent, and easy-to-use API.
Key Classes:
HttpClient: The main entry point for sending requests.HttpRequest: Represents an HTTP request, including its URI, method (GET, POST, etc.), and headers.HttpResponse: Represents the response received from the server, including the status code, headers, and body.
Example: Sending a GET Request with Custom Headers
This example sends a GET request to https://api.github.com and includes a User-Agent and an Accept header.
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
public class ModernHttpClientExample {
public static void main(String[] args) {
// 1. Create an HttpClient
HttpClient client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.connectTimeout(Duration.ofSeconds(10))
.build();
// 2. Create an HttpRequest with headers
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.github.com"))
.header("User-Agent", "My Java App") // Add a custom header
.header("Accept", "application/vnd.github.v3+json") // Request JSON response
.GET() // Specify the GET method
.build();
try {
// 3. Send the request and get the response
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
// 4. Print the results
System.out.println("Status Code: " + response.statusCode());
System.out.println("Response Headers: " + response.headers());
System.out.println("--- Response Body ---");
System.out.println(response.body());
} catch (Exception e) {
e.printStackTrace();
}
}
}
Example: Sending a POST Request with a JSON Body and Headers
This example sends a JSON payload in a POST request.

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.Map;
public class PostRequestExample {
public static void main(String[] args) {
HttpClient client = HttpClient.newBuilder().build();
String jsonBody = "{\"name\":\"John Doe\", \"email\":\"john.doe@example.com\"}";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://httpbin.org/post"))
.header("Content-Type", "application/json") // Crucial for APIs expecting JSON
.header("Accept", "application/json")
.timeout(Duration.ofSeconds(10))
.POST(HttpRequest.BodyPublishers.ofString(jsonBody))
.build();
try {
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Status Code: " + response.statusCode());
System.out.println("Response Body: " + response.body());
} catch (Exception e) {
e.printStackTrace();
}
}
}
The Classic Way: HttpURLConnection (Legacy)
Before Java 11, java.net.HttpURLConnection was the standard, built-in way. It's more verbose and less flexible than the modern client. You might still encounter it in older codebases.
Key Concepts:
- You get a connection object from a
URL. - You set headers using the
setRequestProperty(key, value)method. - You write the request body using the
getOutputStream(). - You read the response using the
getInputStream().
Example: GET Request with Headers
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class ClassicHttpUrlConnectionExample {
public static void main(String[] args) {
try {
URL url = new URL("https://api.github.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// Set request method
connection.setRequestMethod("GET");
// Set headers
connection.setRequestProperty("User-Agent", "My Java App");
connection.setRequestProperty("Accept", "application/json");
// Get the response code
int responseCode = connection.getResponseCode();
System.out.println("Response Code: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) { // success
BufferedReader in = new BufferedReader(
new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// print result
System.out.println("--- Response Body ---");
System.out.println(response.toString());
} else {
System.out.println("GET request failed");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Popular Third-Party Libraries
These libraries offer more features, better performance, and often a simpler API than the built-in options.
A. Apache HttpClient
Very powerful, flexible, and widely used, especially in enterprise applications. It requires adding a dependency (e.g., in Maven).
Maven Dependency:

<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.3.1</version>
</dependency>
Example:
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.HttpClients;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.impl.classic.CloseableHttpResponse;
public class ApacheHttpClientExample {
public static void main(String[] args) {
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpGet request = new HttpGet("https://api.github.com");
// Set headers
request.addHeader("User-Agent", "My Java App");
request.addHeader("Accept", "application/json");
try (CloseableHttpResponse response = httpClient.execute(request)) {
System.out.println("Status Code: " + response.getCode());
String responseBody = EntityUtils.toString(response.getEntity());
System.out.println("--- Response Body ---");
System.out.println(responseBody);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
B. OkHttp
Extremely popular, especially for Android development, but also great for Java. It's known for its simplicity and powerful features like connection pooling and interceptors.
Maven Dependency:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
</dependency>
Example:
import okhttp3.*;
import java.io.IOException;
public class OkHttpExample {
public static void main(String[] args) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://api.github.com")
.header("User-Agent", "My Java App")
.header("Accept", "application/json")
.build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
System.out.println("Status Code: " + response.code());
System.out.println("--- Response Body ---");
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}
Common HTTP Headers and Examples
Here are some of the most important HTTP headers you'll work with.
| Header | Purpose | Example Value |
|---|---|---|
Authorization |
Supplies credentials to authenticate a user agent with a server. | Bearer abc123..., Basic YWxhZGRpbjpvcGVuc2VzYW1l |
Content-Type |
Indicates the media type of the resource. Crucial for POST/PUT requests. | application/json, text/html, application/x-www-form-urlencoded |
Accept |
Tells the server what content types the client can understand. | application/json, text/html, (accept anything) |
User-Agent |
Identifies the client software (e.g., browser, app, script) making the request. | My Java App/1.0, Mozilla/5.0 ... |
Content-Length |
The size of the request body in bytes. Often set automatically by the client. | 123 |
Content-Encoding |
The compression algorithm used on the request/response body. | gzip, deflate |
Accept-Encoding |
Tells the server which compression algorithms the client can accept. | gzip, deflate |
X-Custom-Header |
Custom headers for application-specific information. The X- prefix is a convention. |
X-Request-ID: 789-abc-456 |
Summary: Which One to Use?
| Method | Pros | Cons | Best For |
|---|---|---|---|
java.net.http.HttpClient |
Modern, built-in, fluent API, supports HTTP/2, no external dependencies. | Requires Java 11+. | All new Java projects. The standard choice. |
HttpURLConnection |
Built-in, no dependencies. | Verbose, clunky API, less flexible, poor performance for complex use cases. | Quick scripts or maintaining old Java 8 or earlier projects. |
| Apache HttpClient | Extremely powerful and flexible, feature-rich, mature. | More complex setup (requires dependency), heavier. | Enterprise applications, complex HTTP scenarios, or when you need fine-grained control. |
| OkHttp | Simple and elegant API, great performance, excellent for Android, powerful interceptors. | Requires an external dependency. | Android development, or when you prefer a more modern, lightweight third-party library for Java. |
