Interface HttpResponse.MultiSubscriber<U,T>
-
- Type Parameters:
U
- a type representing the aggregated resultsT
- a type representing all of the response bodies
- Enclosing class:
- HttpResponse<T>
public static interface HttpResponse.MultiSubscriber<U,T>
A response subscriber for a HTTP/2 multi response.
Incubating Feature. Will be removed in a future release.A multi response comprises a main response, and zero or more additional responses. Each additional response is sent by the server in response to requests (PUSH_PROMISEs) that the server also generates. Additional responses are typically resources that the server expects the client will need which are related to the initial request.
Note. Instead of implementing this interface, applications should consider first using the mechanism (built on this interface) provided by
MultiSubscriber.asMap()
which is a slightly simplified, but also general purpose interface.The server generated requests are also known as push promises. The server is permitted to send any number of these requests up to the point where the main response is fully received. Therefore, after completion of the main response, the final number of additional responses is known. Additional responses may be canceled, but given that the server does not wait for any acknowledgment before sending the response, this must be done quickly to avoid unnecessary data transmission.
MultiSubscriber
s are parameterized with a typeU
which represents some meaningful aggregate of the responses received. This would typically be a collection of response or response body objects.- Since:
- 9
-
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Modifier and Type Method Description static <V> HttpResponse.MultiSubscriber<MultiMapResult<V>,V>
asMap(Function<HttpRequest,Optional<HttpResponse.BodyHandler<V>>> reqHandler)
Returns a general purpose handler for multi responses.static <V> HttpResponse.MultiSubscriber<MultiMapResult<V>,V>
asMap(Function<HttpRequest,Optional<HttpResponse.BodyHandler<V>>> reqHandler, boolean completion)
Returns a general purpose handler for multi responses.CompletableFuture<U>
completion(CompletableFuture<Void> onComplete, CompletableFuture<Void> onFinalPushPromise)
Returns aCompletableFuture
<U>
which completes when the aggregate result object itself is available.void
onError(HttpRequest request, Throwable t)
Called if an error occurs receiving a response.Optional<HttpResponse.BodyHandler<T>>
onPushPromise(HttpRequest pushPromise)
Called for each push promise that is received.HttpResponse.BodyHandler<T>
onRequest(HttpRequest request)
Called for the main request from the user.void
onResponse(HttpResponse<T> response)
Called for each response received.
-
-
-
Method Detail
-
onRequest
HttpResponse.BodyHandler<T> onRequest(HttpRequest request)
Called for the main request from the user. ThisHttpRequest
parameter is the request that was supplied toHttpClient.sendAsync(HttpRequest, MultiSubscriber)
. The implementation must return anHttpResponse.BodyHandler
for the response body.- Parameters:
request
- the request- Returns:
- an optional body handler
-
onPushPromise
Optional<HttpResponse.BodyHandler<T>> onPushPromise(HttpRequest pushPromise)
Called for each push promise that is received. TheHttpRequest
parameter represents the PUSH_PROMISE. The implementation must return anOptional
ofHttpResponse.BodyHandler
for the response body. Different handlers (of the same type) can be returned for different pushes within the same multi send. If no handler (an emptyOptional
) is returned, then the push will be canceled. If required, theCompletableFuture<Void>
supplied to theonFinalPushPromise
parameter ofcompletion(CompletableFuture, CompletableFuture)
can be used to determine when the final PUSH_PROMISE is received.- Parameters:
pushPromise
- the push promise- Returns:
- an optional body handler
-
onResponse
void onResponse(HttpResponse<T> response)
Called for each response received. For each request either one of onResponse() or onError() is guaranteed to be called, but not both.Note: The reason for switching to this callback interface rather than using CompletableFutures supplied to onRequest() is that there is a subtle interaction between those CFs and the CF returned from completion() (or when onComplete() was called formerly). The completion() CF will not complete until after all of the work done by the onResponse() calls is done. Whereas if you just create CF's dependent on a supplied CF (to onRequest()) then the implementation has no visibility of the dependent CFs and can't guarantee to call onComplete() (or complete the completion() CF) after the dependent CFs complete.
- Parameters:
response
- the response received
-
onError
void onError(HttpRequest request, Throwable t)
Called if an error occurs receiving a response. For each request either one of onResponse() or onError() is guaranteed to be called, but not both.- Parameters:
request
- the main request or subsequent push promiset
- the Throwable that caused the error
-
completion
CompletableFuture<U> completion(CompletableFuture<Void> onComplete, CompletableFuture<Void> onFinalPushPromise)
Returns aCompletableFuture
<U>
which completes when the aggregate result object itself is available. It is expected that the returnedCompletableFuture
will depend on one of the givenCompletableFuture<Void
s which themselves complete after all individual responses associated with the multi response have completed, or after all push promises have been received. This method is called afteronRequest(HttpRequest)
but before any other methods.- Implementation Note:
- Implementations might follow the pattern shown below
CompletableFuture<U> completion( CompletableFuture<Void> onComplete, CompletableFuture<Void> onFinalPushPromise) { return onComplete.thenApply((v) -> { U u = ... instantiate and populate a U instance return u; }); }
- Parameters:
onComplete
- a CompletableFuture which completes after all responses have been received relating to this multi request.onFinalPushPromise
- CompletableFuture which completes after all push promises have been received.- Returns:
- the aggregate CF response object
-
asMap
static <V> HttpResponse.MultiSubscriber<MultiMapResult<V>,V> asMap(Function<HttpRequest,Optional<HttpResponse.BodyHandler<V>>> reqHandler, boolean completion)
Returns a general purpose handler for multi responses. The aggregated result object produced by this handler is aMap<HttpRequest,CompletableFuture<HttpResponse<V>>>
. Each request (both the original user generated request and each server generated push promise) is returned as a key of the map. The value corresponding to each key is aCompletableFuture<HttpResponse<V>>
.There are two ways to use these handlers, depending on the value of the completion parameter. If completion is true, then the aggregated result will be available after all responses have themselves completed. If completion is false, then the aggregated result will be available immediately after the last push promise was received. In the former case, this implies that all the CompletableFutures in the map values will have completed. In the latter case, they may or may not have completed yet.
The simplest way to use these handlers is to set completion to
true
, and then all (results) values in the Map will be accessible without blocking.See
asMap(java.util.function.Function, boolean)
for a code sample of using this interface.See
asMap(Function, boolean)
for a code sample of using this interface.- Type Parameters:
V
- the body type used for all responses- Parameters:
reqHandler
- a function invoked for the user's request and each push promisecompletion
-true
if the aggregate CompletableFuture completes after all responses have been received, orfalse
after all push promises received- Returns:
- a MultiSubscriber
-
asMap
static <V> HttpResponse.MultiSubscriber<MultiMapResult<V>,V> asMap(Function<HttpRequest,Optional<HttpResponse.BodyHandler<V>>> reqHandler)
Returns a general purpose handler for multi responses. This is a convenience method which invokesasMap(Function, true)
meaning that the aggregate result object completes after all responses have been received.Example usage:
HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://www.foo.com/")) .GET() .build(); HttpClient client = HttpClient.newHttpClient(); Map<HttpRequest,CompletableFuture<HttpResponse<String>>> results = client .sendAsync(request, MultiSubscriber.asMap( (req) -> Optional.of(HttpResponse.BodyHandler.asString()))) .join();
The lambda in this example is the simplest possible implementation, where neither the incoming requests are examined, nor the response headers, and every push that the server sends is accepted. When the join() call returns, all
HttpResponse
s and their associated body objects are available.- Type Parameters:
V
- the body type used for all responses- Parameters:
reqHandler
- a function invoked for each push promise and the main request- Returns:
- a MultiSubscriber
-
-