Of course! Here is a comprehensive guide on how to perform a POST request using the HttpClient in Java, covering the modern Java 11+ java.net.http.HttpClient and the classic Apache HttpClient 5.x.

Summary: Which One to Use?
| Feature | java.net.http.HttpClient (Java 11+) |
Apache HttpClient 5.x |
|---|---|---|
| Dependency | Built-in to Java 11 and later. | Requires adding a library (httpclient5). |
| Ease of Use | Very modern, fluent, and concise API. | Extremely mature, powerful, and highly configurable. |
| Async Support | First-class citizen, using CompletableFuture. |
Excellent async support, using Future and reactive streams. |
| Best For | New projects on Java 11+, simplicity, and standardization. | Legacy codebases, complex requirements, or when you need maximum flexibility. |
Using java.net.http.HttpClient (Modern, Recommended for Java 11+)
This is the standard, built-in HTTP client in modern Java. It's non-blocking by default and has a clean, fluent API.
Step 1: No Dependencies Needed!
If you are using Java 11 or newer, you don't need to add any external libraries. The java.net.http package is part of the standard library.
Step 2: Code Example
Here's a complete example showing how to send a POST request with a JSON payload and handle the response.
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.net.http.HttpResponse.BodyHandlers;
import java.time.Duration;
public class JavaHttpClientPostExample {
public static void main(String[] args) {
// The URL of the API endpoint
String url = "https://jsonplaceholder.typicode.com/posts";
// The JSON payload to send
String jsonPayload = """
{
"title": "foo",
"body": "bar",
"userId": 1
}
""";
// 1. Create an HttpClient
HttpClient client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2) // Use HTTP/2 if possible
.connectTimeout(Duration.ofSeconds(10)) // Set a connection timeout
.build();
// 2. Create an HttpRequest
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/json") // Set the content type
.POST(BodyPublishers.ofString(jsonPayload)) // Set the request body
.build();
try {
// 3. Send the request and get the response
System.out.println("Sending POST request to: " + url);
System.out.println("Payload: " + jsonPayload);
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
// 4. Process the response
System.out.println("\n--- Response ---");
System.out.println("Status Code: " + response.statusCode());
System.out.println("Response Body: " + response.body());
} catch (Exception e) {
System.err.println("An error occurred: " + e.getMessage());
e.printStackTrace();
}
}
}
Key Components Explained:
HttpClient: The main entry point. You configure it with things like the HTTP version (HTTP/1.1 or HTTP/2) and timeouts.HttpRequest: Represents the request to be sent. You specify the URI, headers, and the body.uri(URI.create(url)): The target URL.header("Content-Type", "application/json"): Crucial for APIs that expect JSON. It tells the server what kind of data you're sending.POST(BodyPublishers.ofString(jsonPayload)): This sets the HTTP method to POST and provides the request body.BodyPublishershas several static methods for different body types (e.g.,ofByteArray,ofFile,ofInputStream).
client.send(...): This is a synchronous call. The thread will block until the response is received.- The second argument,
BodyHandlers.ofString(), tells the client to process the response body as aString. Other options includeofByteArray(),ofFile(), etc.
- The second argument,
HttpResponse<String>: The object containing the server's response, including the status code, headers, and the body as aString.
How to Send Form Data (application/x-www-form-urlencoded)
If you need to send form data instead of JSON, you can use the URLEncoder to build the body string.

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
// ... inside the main method ...
// Form data to send
String username = "john.doe";
String password = "secret123";
// Encode the form data
String encodedUsername = URLEncoder.encode(username, StandardCharsets.UTF_8);
String encodedPassword = URLEncoder.encode(password, StandardCharsets.UTF_8);
String formData = "username=" + encodedUsername + "&password=" + encodedPassword;
// Create the request
HttpRequest formRequest = HttpRequest.newBuilder()
.uri(URI.create("https://example.com/api/login"))
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(BodyPublishers.ofString(formData))
.build();
// ... send the request ...
Using Apache HttpClient 5.x (Classic, Powerful, Flexible)
This is the de-facto standard for many Java applications, especially those built on older Java versions or requiring advanced features like connection pooling and complex retry logic.
Step 1: Add the Dependency
You need to add the Apache HttpClient library to your project. If you're using Maven, add this to your pom.xml:
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.3.1</version> <!-- Check for the latest version -->
</dependency>
Step 2: Code Example
This example does the same thing as the one above: sends a JSON POST request.
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.entity.StringEntity;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.apache.hc.core5.net.URIBuilder;
import java.net.URI;
import java.nio.charset.StandardCharsets;
public class ApacheHttpClientPostExample {
public static void main(String[] args) {
String url = "https://jsonplaceholder.typicode.com/posts";
String jsonPayload = """
{
"title": "foo",
"body": "bar",
"userId": 1
}
""";
// 1. Create a CloseableHttpClient
// It's best practice to manage the client lifecycle (create and close)
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
// 2. Create an HttpPost object
HttpPost httpPost = new HttpPost(url);
// 3. Set the request headers
httpPost.setHeader("Content-Type", "application/json");
httpPost.setHeader("Accept", "application/json");
// 4. Set the request body
StringEntity entity = new StringEntity(jsonPayload, ContentType.APPLICATION_JSON);
httpPost.setEntity(entity);
System.out.println("Sending POST request to: " + url);
System.out.println("Payload: " + jsonPayload);
// 5. Execute the request
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
// 6. Process the response
System.out.println("\n--- Response ---");
System.out.println("Status Code: " + response.getCode());
HttpEntity responseEntity = response.getEntity();
if (responseEntity != null) {
// Read the response content as a String
String responseBody = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
System.out.println("Response Body: " + responseBody);
}
// Ensure the response entity is fully consumed to release resources
EntityUtils.consume(responseEntity);
}
} catch (Exception e) {
System.err.println("An error occurred: " + e.getMessage());
e.printStackTrace();
}
}
}
Key Components Explained:
CloseableHttpClient: The main client object. It's recommended to wrap it in atry-with-resourcesblock to ensure it's closed properly, which releases underlying system resources like connections.HttpPost: The class that represents a POST HTTP request.StringEntity: Used to wrap the JSON string into anHttpEntitythat can be attached to the request. You also specify itsContentType.- **`

