Issue
The legacy java http client provided an OutputStream
using URLConnection.getOutputStream
. Writing a json body for example worked like the following:
final URLConnection urlConnection = ...;
try (OutputStreamWriter writer = new OutputStreamWriter(urlConnection.getOutputStream())) {
new Gson().toJson(someJsonObject, writer);
}
What's the equivalent way of stream-writing a request body with the new java 11 http client?
The only alternative I found is to write the entire output into a String
or byte[]
and use BodyPublishers.ofString/ofByteArray
, however this seems rather inefficient to me for larger requests.
Solution
You can use Methanol's WritableBodyPublisher
. It allows you to stream the request body through an OutputStream
or a WritableByteChannel
. The publisher buffers the body in memory as you're writing it. If you want it to get sent while writing you'll need to either use sendAsync
beforehand or do the writing in another thread. This is somewhat similar to URLConnection
's behavior.
var publisher = WritableBodyPublisher.create();
var request = HttpRequest.newBuilder()
.uri(URI.create("https://example.com"))
.POST(publisher)
.build();
var responseAsync = client.sendAsync(request, BodyHandlers.ofString());
try (var writer = new OutputStreamWriter(publisher.outputStream())) {
new Gson().toJson(someJsonObject, writer);
}
Answered By - Moataz Abdelnasser
Answer Checked By - Cary Denson (JavaFixing Admin)