Java › Java Networking & HTTP Client
How would you implement a custom BodySubscriber or BodyHandler to stream a very large HTTP response body incrementally, rather than buffering the entire response into memory at once?
AdvancedAnswer
HttpResponse.BodyHandlers provides several built-in options beyond the common ofString()/ofByteArray() (which fully buffer the response body in memory before returning), including ofInputStream() (returns a standard InputStream you can read incrementally) and ofLines() (returns a Stream<String> of lines, lazily evaluated) -- for genuinely custom streaming processing needs, implementing your own BodySubscriber<T> gives full low-level control over how response body bytes are consumed as they arrive over the network, letting you process a very large response (like a multi-gigabyte file download) incrementally without ever holding the complete body in memory simultaneously.
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://example.com/large-file.zip"))
.build();
// Stream the response body directly to a file, without buffering it fully in memory
HttpResponse<Path> response = client.send(request,
HttpResponse.BodyHandlers.ofFile(Path.of("downloaded-file.zip")));
// Or process line-by-line for a large text response
HttpResponse<Stream<String>> lineResponse = client.send(request, HttpResponse.BodyHandlers.ofLines());
lineResponse.body().forEach(line -> processLine(line));Real-world example A data-synchronization service downloading multi-gigabyte export files from a partner API uses HttpResponse.BodyHandlers.ofFile() to stream the response directly to disk incrementally, avoiding the out-of-memory risk that buffering the entire multi-gigabyte response into a byte array or String first would create.