A
ContentProvider that allows to add content after
Request#send(Response.CompleteListener)has been called, therefore providing the request content at a later time.
DeferredContentProvider can only be used in conjunction with
Request#send(Response.CompleteListener) (and not with its blocking counterpart
Request#send())
because it provides content asynchronously.
The deferred content is provided once and then fully consumed.
Invocations to the
#iterator() method after the first will return an "empty" iterator
because the stream has been consumed on the first invocation.
However, it is possible for subclasses to override
#offer(ByteBuffer) and
#close() to copy
the content to another location (for example a file) and be able to support multiple invocations
of of
#iterator() returning the iterator provided by this
class on the first invocation, and an iterator on the bytes copied to the other location
for subsequent invocations.
Typical usage of
DeferredContentProvider is in asynchronous proxies, where HTTP headers arrive
separately from HTTP content chunks.
The deferred content must be provided through
#offer(ByteBuffer), which can be invoked multiple
times, and when all content has been provided it must be signaled with a call to
#close().
Example usage:
HttpClient httpClient = ...;
// Use try-with-resources to autoclose DeferredContentProvider
try (DeferredContentProvider content = new DeferredContentProvider())
{
httpClient.newRequest("localhost", 8080)
.content(content)
.send(new Response.CompleteListener()
{
@Override
public void onComplete(Result result)
{
// Your logic here
}
});
// At a later time...
content.offer(ByteBuffer.wrap("some content".getBytes()));
}