HttpClient sends HTTP requests using reusable client configuration while each HttpRequest describes one request’s URI, method, headers, and deadline.
Java HttpClient: request policy, deadlines, and response size
Java 11+. Use a JDK that supports this release.
Reuse transport policy
This program constructs a client and an HTTPS GET request without contacting the network. It prints the configured method and host so the example runs offline. Executing send is a separate operation that needs an endpoint, response policy, and integration tests.
A connect timeout bounds connection establishment; a request timeout concerns the request. Neither setting defines a complete retry budget for a batch. Decide the maximum elapsed operation time and stop retries when that budget is exhausted.
Redirects are disabled here. Forwarding credentials or following a user-provided URL deserves a deliberate host and redirect policy. Constructing a syntactically valid URI does not prove the destination is permitted.
Choose the body handler before sending
Reading a response into a String retains the full body. Large or untrusted responses require an actual size budget and a streaming consumption strategy. A Content-Length header can help planning but cannot replace enforcement.
A 404 or 500 response is still an HTTP response, not necessarily an IOException. Interpret status codes before treating the payload as success. On interruption, stop work or preserve the thread’s interrupt signal when translating the error.
Retries are a protocol decision. A repeated GET and a repeated payment POST have different consequences. An idempotency key is useful only when the receiving service implements a matching contract.
Working program
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.time.Duration;
public class ShipmentRequestPolicy {
public static void main(String[] args) {
HttpClient client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(3))
.followRedirects(HttpClient.Redirect.NEVER)
.build();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.aitrove.in/shipments"))
.timeout(Duration.ofSeconds(8))
.header("Accept", "application/json")
.GET().build();
System.out.println(request.method() + " " + request.uri().getHost());
System.out.println("redirects=" + client.followRedirects());
}
}Output
GET api.aitrove.in
redirects=NEVERCost and design choices
Building a request performs bounded setup for the supplied metadata. Network execution adds connection, TLS, server, and body costs; this offline program makes no throughput claim.
Client reuse can retain connection-related resources. Scope its lifetime to the service that owns it and apply a shutdown strategy appropriate to the target JDK. The example’s baseline is Java 11, not a promise about every later release.
Common Mistakes
- Do not call a response successful solely because send returned.
- Do not load an unlimited response into memory.
- Do not swallow InterruptedException and continue retrying.
Connect the contracts
Compare a single request with bounded HTTP retries before adding a retry loop.
Compare the boundary explained in Failure handling with the assumptions made by this program.
Apply this contract in Spring
Spring MVC CORS: a browser-origin policy is not authentication, Spring Boot receipt API project: build, test and inspect the limits. These lessons keep framework assembly separate from the Java contract.
