Of course! Working with HTTP headers in Java is a fundamental task, especially when building web applications or making HTTP requests. The approach differs depending on whether you are sending a request or handling a response.

Here’s a comprehensive guide covering the most common scenarios, using both modern Java's HttpClient (Java 11+) and the classic HttpURLConnection.
Reading HTTP Headers from a Response (Client-Side)
This is when your Java application acts as a client and receives a response from a server. You want to inspect the headers sent back by the server.
Using Modern HttpClient (Java 11+)
This is the recommended, modern approach. It's more powerful, flexible, and easier to use.
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.List;
import java.util.Map;
public class ReadHeadersHttpClient {
public static void main(String[] args) {
// 1. Create an HttpClient
HttpClient client = HttpClient.newHttpClient();
// 2. Create an HttpRequest
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://httpbin.org/get"))
.build();
try {
// 3. Send the request and get the response
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
// 4. Get the headers from the response
// The headers are stored in a Map-like structure
Map<String, List<String>> headers = response.headers().map();
System.out.println("Status Code: " + response.statusCode());
System.out.println("--- Response Headers ---");
// 5. Iterate and print the headers
headers.forEach((name, values) -> {
System.out.println(name + ": " + String.join(", ", values));
});
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
Key Points:

HttpResponse.headers()returns anHttpResponse.Headersobject, which behaves like aMap<String, List<String>>.- A header name can have multiple values (e.g.,
Set-Cookie), which is why it's aList<String>.
Using Classic HttpURLConnection
This is the older, standard way before Java 11. It's more verbose.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class ReadHeadersHttpURLConnection {
public static void main(String[] args) {
try {
URL url = new URL("https://httpbin.org/get");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// Make the request (implicitly by calling getInputStream() or getResponseCode())
int responseCode = connection.getResponseCode();
System.out.println("Status Code: " + responseCode);
System.out.println("--- Response Headers ---");
// 1. Get a single header by name
String contentType = connection.getHeaderField("Content-Type");
System.out.println("Content-Type: " + contentType);
// 2. Get all headers
// The field is numbered starting from 1. 0 is the status line.
for (int i = 1; ; i++) {
String headerName = connection.getHeaderFieldKey(i);
String headerValue = connection.getHeaderField(i);
if (headerName == null && headerValue == null) {
break; // End of headers
}
if (headerName != null) {
System.out.println(headerName + ": " + headerValue);
}
}
// It's good practice to disconnect
connection.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Setting HTTP Headers in a Request (Client-Side)
This is when your Java application acts as a client and wants to send custom headers to a server.
Using Modern HttpClient (Java 11+)
You use the header() method of the HttpRequest.Builder.
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 SetHeadersHttpClient {
public static void main(String[] args) {
HttpClient client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.connectTimeout(Duration.ofSeconds(10))
.build();
// Create a request with multiple headers
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://httpbin.org/post"))
.header("Content-Type", "application/json") // Set a single header
.header("Accept", "application/json")
.header("Custom-Header", "MyCustomValue123") // Set a custom header
.POST(HttpRequest.BodyPublishers.ofString("{\"key\":\"value\"}")) // Add a body to make it a POST
.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 (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
Key Points:

- The
header(String name, String value)method can be called multiple times to add more headers. POST,PUT, etc., are set using methods like.POST().
Using Classic HttpURLConnection
You use the setRequestProperty() method.
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class SetHeadersHttpURLConnection {
public static void main(String[] args) {
try {
URL url = new URL("https://httpbin.org/post");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// Set the request method
connection.setRequestMethod("POST");
// Set headers
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Accept", "application/json");
connection.setRequestProperty("Custom-Header", "MyCustomValue123");
// Enable writing to the connection (for POST/PUT)
connection.setDoOutput(true);
// Write the request body
String jsonInputString = "{\"key\":\"value\"}";
try (OutputStream os = connection.getOutputStream()) {
byte[] input = jsonInputString.getBytes("utf-8");
os.write(input, 0, input.length);
}
// Get the response code
int responseCode = connection.getResponseCode();
System.out.println("Status Code: " + responseCode);
connection.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Handling HTTP Headers in a Server (e.g., with Spring Boot)
When you are building a server, you typically use a framework like Spring Boot. The request is represented as an HttpServletRequest object.
Accessing Request Headers in a Spring Boot Controller
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
@RestController
public class HeaderController {
// Method 1: Using HttpServletRequest to get ALL headers
@GetMapping("/headers/all")
public String getAllHeaders(HttpServletRequest request) {
StringBuilder response = new StringBuilder();
Enumeration<String> headerNames = request.getHeaderNames();
response.append("--- All Request Headers ---\n");
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
String headerValue = request.getHeader(headerName);
response.append(headerName).append(": ").append(headerValue).append("\n");
}
return response.toString();
}
// Method 2: Using @RequestHeader to get a SPECIFIC header
// This is the most common and convenient way.
@GetMapping("/headers/user-agent")
public String getUserAgent(@RequestHeader("User-Agent") String userAgent) {
return "The User-Agent is: " + userAgent;
}
// Method 3: Using @RequestHeader with a default value if the header is missing
@GetMapping("/headers/authorization")
public String getAuthorization(
@RequestHeader(value = "Authorization", defaultValue = "Bearer <default-token>") String authHeader) {
return "The Authorization header is: " + authHeader;
}
}
Key Points:
HttpServletRequest.getHeader(String name)gets the value of a single header.HttpServletRequest.getHeaderNames()gets anEnumerationof all header names.- The
@RequestHeaderannotation in Spring is a powerful shortcut that automatically extracts a header and can even convert its type. - If a required header is missing, Spring will return an
HTTP 400 Bad Requesterror. You can provide adefaultValueto make it optional.
Summary Table
| Task | Modern HttpClient (Java 11+) |
Classic HttpURLConnection |
Spring Boot (@RestController) |
|---|---|---|---|
| Read Response Headers | response.headers().map() |
connection.getHeaderField(name) or loop with i |
request.getHeader(name) |
| Set Request Headers | HttpRequest.Builder.header("Name", "Value") |
connection.setRequestProperty("Name", "Value") |
N/A (Client-side) |
| Access Request Headers | N/A (It's a client library) | N/A (It's a client library) | @RequestHeader("Name") String headerValue |
