Package org.asynchttpclient.handler
Class BodyDeferringAsyncHandler
- java.lang.Object
-
- org.asynchttpclient.handler.BodyDeferringAsyncHandler
-
- All Implemented Interfaces:
AsyncHandler<Response>
public class BodyDeferringAsyncHandler extends Object implements AsyncHandler<Response>
An AsyncHandler that returns Response (without body, so status code and headers only) as fast as possible for inspection, but leaves you the option to defer body consumption.
This class introduces new call: getResponse(), that blocks caller thread as long as headers are received, and return Response as soon as possible, but still pouring response body into supplied output stream. This handler is meant for situations when the "recommended" way (usingclient.prepareGet("http://foo.com/aResource").execute().get()
), which would not work for you, since a potentially large response body is about to be GET-ted, but you need headers first, or you don't know yet (depending on some logic, maybe coming from headers) where to save the body, or you just want to leave body stream to some other component to consume it.
All these above means that this AsyncHandler needs a bit of different handling than "recommended" way. Some examples:
OutputStream fos = ... BodyDeferringAsyncHandler bdah = new BodyDeferringAsyncHandler(fos); // client executes async Future<Response> fr = client.prepareGet("...).execute( bdah); // main thread will block here until headers are available Response response = bdah.getResponse(); // you can continue examine headers while actual body download happens // in separate thread // ... // finally "join" the download fr.get();
PipedOutputStream pout = new PipedOutputStream(); try (PipedInputStream pin = new PipedInputStream(pout)) { BodyDeferringAsyncHandler handler = new BodyDeferringAsyncHandler(pout); ListenableFuture<Response> respFut = client.prepareGet(getTargetUrl()).execute(handler); Response resp = handler.getResponse(); // main thread will block here until headers are available if (resp.getStatusCode() == 200) { try (InputStream is = new BodyDeferringInputStream(respFut, handler, pin)) { // consume InputStream ... } } else { // handle unexpected response status code ... } }
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
BodyDeferringAsyncHandler.BodyDeferringInputStream
A simple helper class that is used to perform automatic "join" for async download and the error checking of the Future of the request.-
Nested classes/interfaces inherited from interface org.asynchttpclient.AsyncHandler
AsyncHandler.State
-
-
Constructor Summary
Constructors Constructor Description BodyDeferringAsyncHandler(OutputStream os)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description protected void
closeOut()
@Nullable Response
getResponse()
This method -- unlike Future<Reponse>.get() -- will block only as long, as headers arrive.AsyncHandler.State
onBodyPartReceived(HttpResponseBodyPart bodyPart)
Invoked as soon as some response body part are received.@Nullable Response
onCompleted()
Invoked once the HTTP response processing is finished.AsyncHandler.State
onHeadersReceived(io.netty.handler.codec.http.HttpHeaders headers)
Invoked as soon as the HTTP headers have been received.void
onRetry()
Notify the callback every time a request is being retried.AsyncHandler.State
onStatusReceived(HttpResponseStatus responseStatus)
Invoked as soon as the HTTP status line has been receivedvoid
onThrowable(Throwable t)
Invoked when an unexpected exception occurs during the processing of the response.AsyncHandler.State
onTrailingHeadersReceived(io.netty.handler.codec.http.HttpHeaders headers)
Invoked when trailing headers have been received.-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Methods inherited from interface org.asynchttpclient.AsyncHandler
onConnectionOffer, onConnectionPoolAttempt, onConnectionPooled, onHostnameResolutionAttempt, onHostnameResolutionFailure, onHostnameResolutionSuccess, onRequestSend, onTcpConnectAttempt, onTcpConnectFailure, onTcpConnectSuccess, onTlsHandshakeAttempt, onTlsHandshakeFailure, onTlsHandshakeSuccess
-
-
-
-
Constructor Detail
-
BodyDeferringAsyncHandler
public BodyDeferringAsyncHandler(OutputStream os)
-
-
Method Detail
-
onThrowable
public void onThrowable(Throwable t)
Description copied from interface:AsyncHandler
Invoked when an unexpected exception occurs during the processing of the response. The exception may have been produced by implementation of onXXXReceived method invocation.- Specified by:
onThrowable
in interfaceAsyncHandler<Response>
- Parameters:
t
- aThrowable
-
onStatusReceived
public AsyncHandler.State onStatusReceived(HttpResponseStatus responseStatus)
Description copied from interface:AsyncHandler
Invoked as soon as the HTTP status line has been received- Specified by:
onStatusReceived
in interfaceAsyncHandler<Response>
- Parameters:
responseStatus
- the status code and test of the response- Returns:
- a
AsyncHandler.State
telling to CONTINUE or ABORT the current processing.
-
onHeadersReceived
public AsyncHandler.State onHeadersReceived(io.netty.handler.codec.http.HttpHeaders headers)
Description copied from interface:AsyncHandler
Invoked as soon as the HTTP headers have been received.- Specified by:
onHeadersReceived
in interfaceAsyncHandler<Response>
- Parameters:
headers
- the HTTP headers.- Returns:
- a
AsyncHandler.State
telling to CONTINUE or ABORT the current processing.
-
onTrailingHeadersReceived
public AsyncHandler.State onTrailingHeadersReceived(io.netty.handler.codec.http.HttpHeaders headers)
Description copied from interface:AsyncHandler
Invoked when trailing headers have been received.- Specified by:
onTrailingHeadersReceived
in interfaceAsyncHandler<Response>
- Parameters:
headers
- the trailing HTTP headers.- Returns:
- a
AsyncHandler.State
telling to CONTINUE or ABORT the current processing.
-
onRetry
public void onRetry()
Description copied from interface:AsyncHandler
Notify the callback every time a request is being retried.- Specified by:
onRetry
in interfaceAsyncHandler<Response>
-
onBodyPartReceived
public AsyncHandler.State onBodyPartReceived(HttpResponseBodyPart bodyPart) throws Exception
Description copied from interface:AsyncHandler
Invoked as soon as some response body part are received. Could be invoked many times. Beware that, depending on the provider (Netty) this can be notified with empty body parts.- Specified by:
onBodyPartReceived
in interfaceAsyncHandler<Response>
- Parameters:
bodyPart
- response's body part.- Returns:
- a
AsyncHandler.State
telling to CONTINUE or ABORT the current processing. Aborting will also close the connection. - Throws:
Exception
- if something wrong happens
-
closeOut
protected void closeOut() throws IOException
- Throws:
IOException
-
onCompleted
@Nullable public @Nullable Response onCompleted() throws IOException
Description copied from interface:AsyncHandler
Invoked once the HTTP response processing is finished.
Gets always invoked as last callback method.- Specified by:
onCompleted
in interfaceAsyncHandler<Response>
- Returns:
- T Value that will be returned by the associated
Future
- Throws:
IOException
-
getResponse
@Nullable public @Nullable Response getResponse() throws InterruptedException, IOException
This method -- unlike Future<Reponse>.get() -- will block only as long, as headers arrive. This is useful for large transfers, to examine headers ASAP, and defer body streaming to it's fine destination and prevent unneeded bandwidth consumption. The response here will contain the very 1st response from server, so status code and headers, but it might be incomplete in case of broken servers sending trailing headers. In that case, the "usual" Future<Response>.get() method will return complete headers, but multiple invocations of getResponse() will always return the 1st cached, probably incomplete one. Note: the response returned by this method will contain everything except the response body itself, so invoking any method like Response.getResponseBodyXXX() will result in error! Also, please note that this method might returnnull
in case of some errors.- Returns:
- a
Response
- Throws:
InterruptedException
- if the latch is interruptedIOException
- if the handler completed with an exception
-
-