com.ning.http.client
Class BodyDeferringAsyncHandler

java.lang.Object
  extended by com.ning.http.client.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 (using client.prepareGet("http://foo.com/aResource").execute().get() would not work for you, since a potentially large response body is about to be GETted, 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:

     FileOutputStream fos = ...
     BodyDeferringAsyncHandler bdah = new BodyDeferringAsyncHandler(fos);
     // client executes async
     Future<Response> fr = client.prepareGet("http://foo.com/aresource").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();
     BodyDeferringAsyncHandler bdah = new BodyDeferringAsyncHandler(pout);
     // client executes async
     Future<Response> fr = client.prepareGet("http://foo.com/aresource").execute(bdah);
     // main thread will block here until headers are available
     Response response = bdah.getResponse();
     if (response.getStatusCode() == 200) {
      InputStream pin = new BodyDeferringInputStream(fr,new PipedInputStream(pout));
      // consume InputStream
      ...
     } else {
      // handle unexpected response status code
      ...
     }
 


Nested Class Summary
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 com.ning.http.client.AsyncHandler
AsyncHandler.STATE
 
Constructor Summary
BodyDeferringAsyncHandler(OutputStream os)
           
 
Method Summary
protected  void closeOut()
           
 Response getResponse()
          This method -- unlike Future.get() -- will block only as long, as headers arrive.
 AsyncHandler.STATE onBodyPartReceived(HttpResponseBodyPart bodyPart)
          Invoked as soon as some response body part are received.
 Response onCompleted()
          Invoked once the HTTP response processing is finished.
 AsyncHandler.STATE onHeadersReceived(HttpResponseHeaders headers)
          Invoked as soon as the HTTP headers has been received.
 AsyncHandler.STATE onStatusReceived(HttpResponseStatus responseStatus)
          Invoked as soon as the HTTP status line has been received
 void onThrowable(Throwable t)
          Invoked when an unexpected exception occurs during the processing of the response.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

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 invokation.

Specified by:
onThrowable in interface AsyncHandler<Response>
Parameters:
t - a Throwable

onStatusReceived

public AsyncHandler.STATE onStatusReceived(HttpResponseStatus responseStatus)
                                    throws Exception
Description copied from interface: AsyncHandler
Invoked as soon as the HTTP status line has been received

Specified by:
onStatusReceived in interface AsyncHandler<Response>
Parameters:
responseStatus - the status code and test of the response
Returns:
a AsyncHandler.STATE telling to CONTINUE or ABORT the current processing.
Throws:
Exception - if something wrong happens

onHeadersReceived

public AsyncHandler.STATE onHeadersReceived(HttpResponseHeaders headers)
                                     throws Exception
Description copied from interface: AsyncHandler
Invoked as soon as the HTTP headers has been received. Can potentially be invoked morethan once if a broken server sent trailling headers.

Specified by:
onHeadersReceived in interface AsyncHandler<Response>
Parameters:
headers - the HTTP headers.
Returns:
a AsyncHandler.STATE telling to CONTINUE or ABORT the current processing.
Throws:
Exception - if something wrong happens

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.

Specified by:
onBodyPartReceived in interface AsyncHandler<Response>
Parameters:
bodyPart - response's body part.
Returns:
a AsyncHandler.STATE telling to CONTINUE or ABORT the current processing.
Throws:
Exception - if something wrong happens

closeOut

protected void closeOut()
                 throws IOException
Throws:
IOException

onCompleted

public 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 interface AsyncHandler<Response>
Returns:
T Value that will be returned by the associated Future
Throws:
IOException

getResponse

public Response getResponse()
                     throws InterruptedException,
                            IOException
This method -- unlike Future.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.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 not that this method might return null in case of some errors.

Returns:
a Response
Throws:
InterruptedException
IOException


Copyright © 2011. All Rights Reserved.