Class HttpResponse.BodyHandlers
- Enclosing interface:
HttpResponse<T>
BodyHandler
that implement various
useful handlers, such as handling the response body as a String, or
streaming the response body to a file.
These implementations do not examine the status code, meaning the
body is always accepted. They typically return an equivalently named
BodySubscriber
. Alternatively, a custom handler can be used to
examine the status code and headers, and return a different body
subscriber, of the same type, as appropriate.
The following are examples of using the predefined body handlers to convert a flow of response body data into common high-level Java objects:
// Receives the response body as a String
HttpResponse<String> response = client
.send(request, BodyHandlers.ofString());
// Receives the response body as a file
HttpResponse<Path> response = client
.send(request, BodyHandlers.ofFile(Paths.get("example.html")));
// Receives the response body as an InputStream
HttpResponse<InputStream> response = client
.send(request, BodyHandlers.ofInputStream());
// Discards the response body
HttpResponse<Void> response = client
.send(request, BodyHandlers.discarding());
- API Note:
- Some body implementations created by body subscribers may need to be properly closed, read, or cancelled for the associated resources to be reclaimed and for the associated request to run to completion.
- Since:
- 11
-
Method Summary
Modifier and TypeMethodDescriptionstatic <T> HttpResponse.BodyHandler
<T> buffering
(HttpResponse.BodyHandler<T> downstreamHandler, int bufferSize) Returns aBodyHandler
which, when invoked, returns a buffering BodySubscriber that buffers data before delivering it to the downstream subscriber.static HttpResponse.BodyHandler
<Void> Returns a response body handler that discards the response body.static HttpResponse.BodyHandler
<Void> fromLineSubscriber
(Flow.Subscriber<? super String> subscriber) Returns a response body handler that returns aBodySubscriber
<Void>
obtained fromBodySubscribers.fromLineSubscriber(subscriber, s -> null, charset, null)
, with the givensubscriber
.static <S extends Flow.Subscriber<? super String>, T>
HttpResponse.BodyHandler<T> fromLineSubscriber
(S subscriber, Function<? super S, ? extends T> finisher, String lineSeparator) Returns a response body handler that returns aBodySubscriber
<T>
obtained fromBodySubscribers.fromLineSubscriber(subscriber, finisher, charset, lineSeparator)
, with the givensubscriber
,finisher
function, and line separator.static HttpResponse.BodyHandler
<Void> fromSubscriber
(Flow.Subscriber<? super List<ByteBuffer>> subscriber) Returns a response body handler that returns aBodySubscriber
<Void>
obtained fromHttpResponse.BodySubscribers.fromSubscriber(Subscriber)
, with the givensubscriber
.static <S extends Flow.Subscriber<? super List<ByteBuffer>>, T>
HttpResponse.BodyHandler<T> fromSubscriber
(S subscriber, Function<? super S, ? extends T> finisher) Returns a response body handler that returns aBodySubscriber
<T>
obtained fromHttpResponse.BodySubscribers.fromSubscriber(Subscriber, Function)
, with the givensubscriber
andfinisher
function.static HttpResponse.BodyHandler
<byte[]> Returns aBodyHandler<byte[]>
that returns aBodySubscriber
<byte[]>
obtained fromBodySubscribers.ofByteArray()
.static HttpResponse.BodyHandler
<Void> ofByteArrayConsumer
(Consumer<Optional<byte[]>> consumer) Returns aBodyHandler<Void>
that returns aBodySubscriber
<Void>
obtained fromBodySubscribers.ofByteArrayConsumer(Consumer)
.static HttpResponse.BodyHandler
<Path> static HttpResponse.BodyHandler
<Path> ofFile
(Path file, OpenOption... openOptions) Returns aBodyHandler<Path>
that returns aBodySubscriber
<Path>
obtained fromBodySubscribers.ofFile(Path,OpenOption...)
.static HttpResponse.BodyHandler
<Path> ofFileDownload
(Path directory, OpenOption... openOptions) Returns aBodyHandler<Path>
that returns aBodySubscriber
<Path
> where the download directory is specified, but the filename is obtained from theContent-Disposition
response header.static HttpResponse.BodyHandler
<InputStream> Returns aBodyHandler<InputStream>
that returns aBodySubscriber
<InputStream>
obtained fromBodySubscribers.ofInputStream
.static HttpResponse.BodyHandler
<Stream<String>> ofLines()
Returns aBodyHandler<Stream<String>>
that returns aBodySubscriber
<Stream<String>>
obtained fromBodySubscribers.ofLines(charset)
.static HttpResponse.BodyHandler
<Flow.Publisher<List<ByteBuffer>>> Returns aBodyHandler<Publisher<List<ByteBuffer>>>
that creates aBodySubscriber
<Publisher<List<ByteBuffer>>>
obtained fromBodySubscribers.ofPublisher()
.static HttpResponse.BodyHandler
<String> ofString()
Returns aBodyHandler<String>
that returns aBodySubscriber
<String>
obtained fromBodySubscribers.ofString(Charset)
.static HttpResponse.BodyHandler
<String> Returns aBodyHandler<String>
that returns aBodySubscriber
<String>
obtained fromBodySubscribers.ofString(Charset)
.static <U> HttpResponse.BodyHandler
<U> replacing
(U value) Returns a response body handler that returns the given replacement value, after discarding the response body.
-
Method Details
-
fromSubscriber
public static HttpResponse.BodyHandler<Void> fromSubscriber(Flow.Subscriber<? super List<ByteBuffer>> subscriber) Returns a response body handler that returns aBodySubscriber
<Void>
obtained fromHttpResponse.BodySubscribers.fromSubscriber(Subscriber)
, with the givensubscriber
.The response body is not available through this, or the
HttpResponse
API, but instead all response body is forwarded to the givensubscriber
, which should make it available, if appropriate, through some other mechanism, e.g. an entry in a database, etc.- API Note:
- This method can be used as an adapter between
BodySubscriber
andFlow.Subscriber
.For example:
TextSubscriber subscriber = new TextSubscriber(); HttpResponse<Void> response = client.sendAsync(request, BodyHandlers.fromSubscriber(subscriber)).join(); System.out.println(response.statusCode());
- Parameters:
subscriber
- the subscriber- Returns:
- a response body handler
-
fromSubscriber
public static <S extends Flow.Subscriber<? super List<ByteBuffer>>, T> HttpResponse.BodyHandler<T> fromSubscriber(S subscriber, Function<? super S, ? extends T> finisher) Returns a response body handler that returns aBodySubscriber
<T>
obtained fromHttpResponse.BodySubscribers.fromSubscriber(Subscriber, Function)
, with the givensubscriber
andfinisher
function.The given
finisher
function is applied after the given subscriber'sonComplete
has been invoked. Thefinisher
function is invoked with the given subscriber, and returns a value that is set as the response's body.- API Note:
- This method can be used as an adapter between
BodySubscriber
andFlow.Subscriber
.For example:
TextSubscriber subscriber = ...; // accumulates bytes and transforms them into a String HttpResponse<String> response = client.sendAsync(request, BodyHandlers.fromSubscriber(subscriber, TextSubscriber::getTextResult)).join(); String text = response.body();
- Type Parameters:
S
- the type of the SubscriberT
- the type of the response body- Parameters:
subscriber
- the subscriberfinisher
- a function to be applied after the subscriber has completed- Returns:
- a response body handler
-
fromLineSubscriber
public static HttpResponse.BodyHandler<Void> fromLineSubscriber(Flow.Subscriber<? super String> subscriber) Returns a response body handler that returns aBodySubscriber
<Void>
obtained fromBodySubscribers.fromLineSubscriber(subscriber, s -> null, charset, null)
, with the givensubscriber
. Thecharset
used to decode the response body bytes is obtained from the HTTP response headers as specified byofString()
, and lines are delimited in the manner ofBufferedReader.readLine()
.The response body is not available through this, or the
HttpResponse
API, but instead all response body is forwarded to the givensubscriber
, which should make it available, if appropriate, through some other mechanism, e.g. an entry in a database, etc.- API Note:
- This method can be used as an adapter between a
BodySubscriber
and a text basedFlow.Subscriber
that parses text line by line.For example:
// A PrintSubscriber that implements Flow.Subscriber<String> // and print lines received by onNext() on System.out PrintSubscriber subscriber = new PrintSubscriber(System.out); client.sendAsync(request, BodyHandlers.fromLineSubscriber(subscriber)) .thenApply(HttpResponse::statusCode) .thenAccept((status) -> { if (status != 200) { System.err.printf("ERROR: %d status received%n", status); } });
- Parameters:
subscriber
- the subscriber- Returns:
- a response body handler
-
fromLineSubscriber
public static <S extends Flow.Subscriber<? super String>, T> HttpResponse.BodyHandler<T> fromLineSubscriber(S subscriber, Function<? super S, ? extends T> finisher, String lineSeparator) Returns a response body handler that returns aBodySubscriber
<T>
obtained fromBodySubscribers.fromLineSubscriber(subscriber, finisher, charset, lineSeparator)
, with the givensubscriber
,finisher
function, and line separator. Thecharset
used to decode the response body bytes is obtained from the HTTP response headers as specified byofString()
.The given
finisher
function is applied after the given subscriber'sonComplete
has been invoked. Thefinisher
function is invoked with the given subscriber, and returns a value that is set as the response's body.- API Note:
- This method can be used as an adapter between a
BodySubscriber
and a text basedFlow.Subscriber
that parses text line by line.For example:
// A LineParserSubscriber that implements Flow.Subscriber<String> // and accumulates lines that match a particular pattern Pattern pattern = ...; LineParserSubscriber subscriber = new LineParserSubscriber(pattern); HttpResponse<List<String>> response = client.send(request, BodyHandlers.fromLineSubscriber(subscriber, s -> s.getMatchingLines(), "\n")); if (response.statusCode() != 200) { System.err.printf("ERROR: %d status received%n", response.statusCode()); }
- Type Parameters:
S
- the type of the SubscriberT
- the type of the response body- Parameters:
subscriber
- the subscriberfinisher
- a function to be applied after the subscriber has completedlineSeparator
- an optional line separator: can benull
, in which case lines will be delimited in the manner ofBufferedReader.readLine()
.- Returns:
- a response body handler
- Throws:
IllegalArgumentException
- if the suppliedlineSeparator
is the empty string
-
discarding
Returns a response body handler that discards the response body.- Returns:
- a response body handler
-
replacing
Returns a response body handler that returns the given replacement value, after discarding the response body.- Type Parameters:
U
- the response body type- Parameters:
value
- the value of U to return as the body, may benull
- Returns:
- a response body handler
-
ofString
Returns aBodyHandler<String>
that returns aBodySubscriber
<String>
obtained fromBodySubscribers.ofString(Charset)
. The body is decoded using the given character set.- Parameters:
charset
- the character set to convert the body with- Returns:
- a response body handler
-
ofFile
Returns aBodyHandler<Path>
that returns aBodySubscriber
<Path>
obtained fromBodySubscribers.ofFile(Path,OpenOption...)
.When the
HttpResponse
object is returned, the body has been completely written to the file, andHttpResponse.body()
returns a reference to itsPath
.- Parameters:
file
- the file to store the body inopenOptions
- any options to use when opening/creating the file- Returns:
- a response body handler
- Throws:
IllegalArgumentException
- if an invalid set of open options are specified
-
ofFile
Returns aBodyHandler<Path>
that returns aBodySubscriber
<Path>
.Equivalent to:
ofFile(file, CREATE, WRITE)
- Parameters:
file
- the file to store the body in- Returns:
- a response body handler
-
ofFileDownload
public static HttpResponse.BodyHandler<Path> ofFileDownload(Path directory, OpenOption... openOptions) Returns aBodyHandler<Path>
that returns aBodySubscriber
<Path
> where the download directory is specified, but the filename is obtained from theContent-Disposition
response header. TheContent-Disposition
header must specify the attachment type and must also contain a filename parameter. If the filename specifies multiple path components only the final component is used as the filename (with the given directory name).When the
HttpResponse
object is returned, the body has been completely written to the file andHttpResponse.body()
returns aPath
object for the file. The returnedPath
is the combination of the supplied directory name and the file name supplied by the server. If the destination directory does not exist or cannot be written to, then the response will fail with anIOException
.- Parameters:
directory
- the directory to store the file inopenOptions
- open options used when opening the file- Returns:
- a response body handler
- Throws:
IllegalArgumentException
- if the given path does not exist, is not of the default file system, is not a directory, is not writable, or if an invalid set of open options are specified
-
ofInputStream
Returns aBodyHandler<InputStream>
that returns aBodySubscriber
<InputStream>
obtained fromBodySubscribers.ofInputStream
.When the
HttpResponse
object is returned, the response headers will have been completely read, but the body may not have been fully received yet. TheHttpResponse.body()
method returns anInputStream
from which the body can be read as it is received.- API Note:
- See
HttpResponse.BodySubscribers.ofInputStream()
for more information.To ensure that all resources associated with the corresponding exchange are properly released the caller must eventually obtain and close the returned stream.
- Returns:
- a streaming response body handler
-
ofLines
Returns aBodyHandler<Stream<String>>
that returns aBodySubscriber
<Stream<String>>
obtained fromBodySubscribers.ofLines(charset)
. Thecharset
used to decode the response body bytes is obtained from the HTTP response headers as specified byofString()
, and lines are delimited in the manner ofBufferedReader.readLine()
.When the
HttpResponse
object is returned, the body may not have been completely received.- API Note:
- To ensure that all resources associated with the corresponding exchange are properly released the caller must eventually obtain and close the returned stream.
- Returns:
- a streaming response body handler
-
ofByteArrayConsumer
public static HttpResponse.BodyHandler<Void> ofByteArrayConsumer(Consumer<Optional<byte[]>> consumer) Returns aBodyHandler<Void>
that returns aBodySubscriber
<Void>
obtained fromBodySubscribers.ofByteArrayConsumer(Consumer)
.When the
HttpResponse
object is returned, the body has been completely written to the consumer.- API Note:
- The subscriber returned by this handler is not flow controlled. Therefore, the supplied consumer must be able to process whatever amount of data is delivered in a timely fashion.
- Parameters:
consumer
- a Consumer to accept the response body- Returns:
- a response body handler
-
ofByteArray
Returns aBodyHandler<byte[]>
that returns aBodySubscriber
<byte[]>
obtained fromBodySubscribers.ofByteArray()
.When the
HttpResponse
object is returned, the body has been completely written to the byte array.- Returns:
- a response body handler
-
ofString
Returns aBodyHandler<String>
that returns aBodySubscriber
<String>
obtained fromBodySubscribers.ofString(Charset)
. The body is decoded using the character set specified in theContent-Type
response header. If there is no such header, or the character set is not supported, thenUTF_8
is used.When the
HttpResponse
object is returned, the body has been completely written to the string.- Returns:
- a response body handler
-
ofPublisher
Returns aBodyHandler<Publisher<List<ByteBuffer>>>
that creates aBodySubscriber
<Publisher<List<ByteBuffer>>>
obtained fromBodySubscribers.ofPublisher()
.When the
HttpResponse
object is returned, the response headers will have been completely read, but the body may not have been fully received yet. TheHttpResponse.body()
method returns aPublisher
<List<ByteBuffer>>
from which the body response bytes can be obtained as they are received. The publisher can and must be subscribed to only once.- API Note:
- See
HttpResponse.BodySubscribers.ofPublisher()
for more information.To ensure that all resources associated with the corresponding exchange are properly released the caller must subscribe to the publisher and conform to the rules outlined in HttpResponse.BodySubscribers.ofPublisher()
- Returns:
- a publishing response body handler
-
buffering
public static <T> HttpResponse.BodyHandler<T> buffering(HttpResponse.BodyHandler<T> downstreamHandler, int bufferSize) Returns aBodyHandler
which, when invoked, returns a buffering BodySubscriber that buffers data before delivering it to the downstream subscriber. TheseBodySubscriber
instances are created by callingBodySubscribers.buffering
with a subscriber obtained from the given downstream handler and thebufferSize
parameter.- Type Parameters:
T
- the response body type- Parameters:
downstreamHandler
- the downstream handlerbufferSize
- the buffer size parameter passed toBodySubscribers.buffering
- Returns:
- a body handler
- Throws:
IllegalArgumentException
- ifbufferSize <= 0
-