JDK 11 HTTP Client API - Handling Request/Response Body Types
Join the DZone community and get the full member experience.
Join For FreeThis article is a supersonic guide to dealing with request and response body types in an HTTP Client API. Let's start with the request body types.
Handling Request Body Types
Setting a request body can be accomplished using HttpRequest.Builder.POST()
and PUT()
or by using method()
(for example, method("PATCH", HttpRequest.BodyPublisher)
). The POST()
and PUT()
take an argument of the HttpRequest.BodyPublisher
type.
The API comes with several implementations of this interface ( BodyPublisher
) in the HttpRequest.BodyPublishers
class, as follows:
-
BodyPublishers.ofString()
-
BodyPublishers.ofFile()
-
BodyPublishers.ofByteArray()
-
BodyPublishers.ofInputStream()
We'll take a look at these implementations in the following sections.
Creating a Body From a String
Creating a body from a string can be accomplished using BodyPublishers.ofString()
, as shown in the following snippet of code:
HttpRequest requestBody = HttpRequest.newBuilder()
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(
"{\"name\": \"morpheus\",\"job\": \"leader\"}"))
.uri(URI.create("https://reqres.in/api/users"))
.build();
For specifying a charset call, use ofString(String s, Charset charset)
.
Creating a body from InputStream
Creating a body from InputStream
can be accomplished using BodyPublishers.ofInputStream()
, as shown in the following snippet of code. (Here, we rely on ByteArrayInputStream
, but, of course, any other InputStream
is suitable):
xxxxxxxxxx
HttpRequest requestBodyOfInputStream = HttpRequest.newBuilder()
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofInputStream(()
-> inputStream("user.json")))
.uri(URI.create("https://reqres.in/api/users"))
.build();
private static ByteArrayInputStream inputStream(String fileName) {
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(
Files.readAllBytes(Path.of(fileName)))) {
return inputStream;
} catch (IOException ex) {
throw new RuntimeException("File could not be read", ex);
}
}
In order to take advantage of lazy creation, InputStream
has to be passed as Supplier
.
Creating a Body From a Byte Array
Creating a body from a byte array can be accomplished using BodyPublishers.ofByteArray()
, as shown in the following snippet of code:
HttpRequest requestBodyOfByteArray = HttpRequest.newBuilder()
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofByteArray(
Files.readAllBytes(Path.of("user.json"))))
.uri(URI.create("https://reqres.in/api/users"))
.build();
We can also send only a part of the byte array using ofByteArray(byte[] buf, int offset, int length)
. Moreover, we can provide data from an Iterable
of byte arrays using ofByteArrays(Iterable<byte[]> iter)
.
Creating a Body From a File
Creating a body from a file can be accomplished using BodyPublishers.ofFile()
, as shown in the following snippet of code:
xxxxxxxxxx
HttpRequest requestBodyOfFile = HttpRequest.newBuilder()
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofFile(Path.of("user.json")))
.uri(URI.create("https://reqres.in/api/users"))
.build();
All the above examples can be found on GitHub. Next, let's handle response body types.
Handling Response Body Types
Handling response body types can be accomplished using HttpResponse.BodyHandler
.
The API comes with several implementations of this interface ( BodyHandler
) in the HttpResponse.BodyHandlers
class, as follows:
-
BodyHandlers.ofByteArray()
-
BodyHandlers.ofFile()
-
BodyHandlers.ofString()
-
BodyHandlers.ofInputStream()
-
BodyHandlers.ofLines()
Considering the following request, let's look at several solutions for handling the response body:
xxxxxxxxxx
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://reqres.in/api/users/2"))
.build();
We'll look at how to handle different types of response bodies in the following sections.
Handling a Response Body as a String
Handling a body response as a string can be accomplished using BodyHandlers.ofString()
, as shown in the following snippet of code:
xxxxxxxxxx
HttpResponse<String> responseOfString
= client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Status code: " + responseOfString.statusCode());
System.out.println("Body: " + responseOfString.body());
For specifying a charset, call ofString(String s, Charset charset)
.
Handling a Response Body as a File
Handling a body response as a file can be accomplished using BodyHandlers.ofFile()
, as shown in the following snippet of code:
xxxxxxxxxx
HttpResponse<Path> responseOfFile = client.send(
request, HttpResponse.BodyHandlers.ofFile(
Path.of("response.json")));
System.out.println("Status code: " + responseOfFile.statusCode());
System.out.println("Body: " + responseOfFile.body());
For specifying the open options, call ofFile(Path file, OpenOption... openOptions)
.
Handling a Response Body as a Byte Array
Handling a body response as a byte array can be accomplished using BodyHandlers.ofByteArray()
, as shown in the following snippet of code:
xxxxxxxxxx
HttpResponse<byte[]> responseOfByteArray = client.send(
request, HttpResponse.BodyHandlers.ofByteArray());
System.out.println("Status code: "
+ responseOfByteArray.statusCode());
System.out.println("Body: "
+ new String(responseOfByteArray.body()));
For consuming the byte array, call ofByteArrayConsumer(Consumer<Optional<byte[]>> consumer)
.
Handling a Response Body as an Input Stream
Handling a body response as InputStream can be accomplished using BodyHandlers.ofInputStream()
, as shown in the following snippet of code:
xxxxxxxxxx
HttpResponse<InputStream> responseOfInputStream = client.send(
request, HttpResponse.BodyHandlers.ofInputStream());
System.out.println("\nHttpResponse.BodyHandlers.ofInputStream():");
System.out.println("Status code: "
+ responseOfInputStream.statusCode());
byte[] allBytes;
try (InputStream fromIs = responseOfInputStream.body()) {
allBytes = fromIs.readAllBytes();
}
System.out.println("Body: "
+ new String(allBytes, StandardCharsets.UTF_8));
Handling a Response Body as a Stream of Strings
Handling a body response as a stream of strings can be accomplished using BodyHandlers.ofLines()
, as shown in the following snippet of code:
xxxxxxxxxx
HttpResponse<Stream<String>> responseOfLines = client.send(
request, HttpResponse.BodyHandlers.ofLines());
System.out.println("Status code: " + responseOfLines.statusCode());
System.out.println("Body: " + responseOfLines.body().collect(toList()));
All the above examples can be found on GitHub.
If you enjoyed this article, then I'm sure you will love my book, Java Coding Problems, which has an entire chapter dedicated to HTTP Client API. Check it out!
Opinions expressed by DZone contributors are their own.
Comments