Since Java 11, the JDK includes a modern HttpClient (java.net.http) for HTTP/1.1 and HTTP/2 calls with no extra library. Testers use it for small utilities: checking links, seeding test data, calling a health endpoint before a suite. For full API test suites, REST Assured is usually more convenient.
// ── HTTP CLIENT (Java 11+) ──
import java.net.http.*;
import java.net.URI;
HttpClient client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.connectTimeout(Duration.ofSeconds(10))
.build();
// GET request
HttpRequest getReq = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/users"))
.header("Accept", "application/json")
.header("Authorization", "Bearer " + token)
.GET()
.build();
HttpResponse<String> response = client.send(getReq,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode()); // 200
System.out.println(response.body()); // JSON string
// POST request
String json = "{\"name\":\"Alice\",\"email\":\"alice@test.com\"}";
HttpRequest postReq = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/users"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();
// Async request
client.sendAsync(getReq, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
// ── SOCKETS (low-level) ──
// Server
ServerSocket server = new ServerSocket(8080);
Socket client = server.accept(); // blocks waiting for connection
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
String message = in.readLine();
out.println("Echo: " + message);
client.close();
// Client
Socket socket = new Socket("localhost", 8080);
PrintWriter out2 = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in2 = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out2.println("Hello Server!");
System.out.println(in2.readLine()); // Echo: Hello Server!
socket.close();
Reading JSON Responses
record User(int id, String name, String email) { }
HttpResponse<String> res = client.send(getReq, HttpResponse.BodyHandlers.ofString());
if (res.statusCode() != 200) {
throw new IllegalStateException("GET /users/7 returned " + res.statusCode() + ": " + res.body());
}
ObjectMapper mapper = new ObjectMapper(); // Jackson
User user = mapper.readValue(res.body(), User.class);
Timeouts and Retries
HttpRequest req = HttpRequest.newBuilder(URI.create(baseUrl + "/health"))
.timeout(Duration.ofSeconds(5)) // per-request timeout
.GET().build();
for (int attempt = 1; attempt <= 3; attempt++) { // wait for the environment before the suite
try {
if (client.send(req, HttpResponse.BodyHandlers.discarding()).statusCode() == 200) break;
} catch (HttpTimeoutException e) { /* retry */ }
Thread.sleep(2000);
}
Set a connect timeout on the client and a request timeout on each call; without them a hung server can block a test run indefinitely.
HttpClient vs REST Assured
| Java HttpClient | REST Assured | |
|---|---|---|
| Dependency | None (JDK 11+) | Library |
| Assertions | Write your own | Built-in given/when/then with JSON path |
| Best for | Utilities, health checks, link checking | API test suites |
FAQs
Which Java version introduced HttpClient?
Java 11 made java.net.http.HttpClient standard (it was an incubator module in Java 9 and 10).
Does Java HttpClient support HTTP/2?
Yes. It uses HTTP/2 by default when the server supports it and falls back to HTTP/1.1; you can force a version with .version(HttpClient.Version.HTTP_1_1).
Should I use HttpClient or REST Assured for API tests?
REST Assured for test suites, because of its fluent assertions and JSON path support; HttpClient for small utilities where you don't want an extra dependency.