Handling Responses
BodyHandlers and status codes.
Handling Responses is a free Java Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Java Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Handling Responses
Every call to the HTTP client returns an HttpResponse<T>. The generic type T is decided by the BodyHandler you pass in. This lesson explores the available handlers and how to interpret status codes.
The HttpResponse API
Key methods on HttpResponse:
statusCode()— the int status.body()— the decoded body of typeT.headers()— response headers.uri()— the final URI (after redirects).version()— HTTP/1.1 or HTTP/2.
BodyHandlers.ofString
The most common handler decodes the body into a String using the charset from the response, defaulting to UTF-8. The response type is HttpResponse<String>.
import java.net.URI;
import java.net.http.*;
public class Main {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://example.com")).build();
HttpResponse<String> res =
client.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(res.body().length());
}
}BodyHandlers.ofByteArray
For binary content such as images, use ofByteArray(). The body type becomes byte[], which you can write to disk or decode yourself.
public class Main {
public static void main(String[] args) {
// ofByteArray() yields HttpResponse<byte[]>
byte[] simulated = { 1, 2, 3, 4 };
System.out.println("Bytes received: " + simulated.length);
}
}BodyHandlers.ofFile
ofFile(path) streams the response directly to disk and gives you an HttpResponse<Path>. This avoids buffering a large download in memory.
import java.net.URI;
import java.net.http.*;
import java.nio.file.Path;
public class Main {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://example.com/file.zip")).build();
HttpResponse<Path> res = client.send(req,
HttpResponse.BodyHandlers.ofFile(Path.of("out.zip")));
System.out.println("Saved to: " + res.body());
}
}BodyHandlers.discarding
When you only care about the status and headers, discarding() throws the body away, producing HttpResponse<Void>. It avoids the cost of buffering.
Checking for Success
A common helper checks whether the status is in the 2xx range before trusting the body.
public class Main {
static boolean isSuccess(int code) {
return code >= 200 && code < 300;
}
public static void main(String[] args) {
System.out.println(isSuccess(204));
System.out.println(isSuccess(404));
}
}Reacting to Status Categories
Switch on the leading digit to branch your logic for success, redirects, and errors.
public class Main {
static String classify(int code) {
return switch (code / 100) {
case 2 -> "Success";
case 3 -> "Redirect";
case 4 -> "Client error";
case 5 -> "Server error";
default -> "Unknown";
};
}
public static void main(String[] args) {
System.out.println(classify(503));
System.out.println(classify(200));
}
}Mapping Bodies with mapping
BodyHandlers.mapping(upstream, fn) wraps another handler and transforms its result. For example, parse a string body into an integer length, all inside the handler.
Reading a Specific Header
To read a response header value, use headers().firstValue(name), which returns an Optional<String>. For all values of a repeated header use allValues(name).
import java.util.Optional;
public class Main {
public static void main(String[] args) {
Optional<String> len = Optional.of("1024");
int contentLength = len.map(Integer::parseInt).orElse(0);
System.out.println("Content-Length: " + contentLength);
}
}Choosing a Handler
- ofString — text and JSON APIs.
- ofByteArray — small binary payloads held in memory.
- ofFile — large downloads streamed to disk.
- ofInputStream — process the body as a stream.
- discarding — status-only requests.
Quick Check
Test your understanding of response handling.
Recap
You learned to interpret HTTP responses:
- HttpResponse exposes
statusCode(),body(), andheaders(). - The BodyHandler determines the body type: String, byte[], Path, Void, or stream.
- Use
ofFilefor large downloads to avoid memory pressure. - Classify status codes by their leading digit and check the 2xx range for success.
- Read headers with
firstValue/allValues.
Frequently asked questions
Is the “Handling Responses” lesson free?
Yes — the full text of “Handling Responses” is free to read here on the web, and the Java Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Java Academy course, upgrade to CoddyKit PRO.
What will I learn in “Handling Responses”?
BodyHandlers and status codes. You practise Java Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Java Academy?
No prior experience is required. Java Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Handling Responses” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Java Academy lesson?
Yes. Every Java Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- java.net.http.HttpClient
- Async Requests
- Request Bodies and Headers
- Handling Responses