如何使用Apache AyncHttpClient发送分块请求

时间:2014-07-12 13:29:42

标签: httprequest apache-httpclient-4.x chunked

我想要发送一个请求正文,一次生成一个部分,但不知道整个长度。换句话说,我需要发送一个分块请求。

我无法找到如何做到这一点。

  

两种类型的连接之间的主要区别是无法使用通常但固有的阻塞java.io.InputStreamjava.io.OutputStream类来表示入站和出站内容的流。 HttpCore NIO提供ContentEncoderContentDecoder接口来处理异步内容传输过程。

     

...

     

非阻塞HTTP连接将触发输出事件,直到内容实体被标记为完全传输。

ContentEncoder encoder = <...>
// Prepare output data
ByteBuffer src = ByteBuffer.allocate(2048);
// Write data out
encoder.write(src);
// Mark content entity as fully transferred when done
encoder.complete();

我查看了org.apache.http.nio.conn.ClientAsyncConnection,但我无法查看输出事件的触发位置。

我可以找到发送文件的示例,但是没有我想要的内容生成。

如何使用AsyncHttpClient发送流式分组请求?

1 个答案:

答案 0 :(得分:0)

您可以使用提供的HttpAsyncRequestProducer之一实现自定义HttpAsyncContentProducer并使其流出内容,或者实现您自己的内容生成逻辑

public class MyAsyncRequestProducer implements HttpAsyncRequestProducer {

    private final HttpHost target;
    private final HttpAsyncContentProducer producer;

    public MyAsyncRequestProducer(
            final HttpHost target,
            final HttpAsyncContentProducer producer) {
        super();
        Args.notNull(target, "HTTP host");
        Args.notNull(producer, "HTTP content producer");
        this.target = target;
        this.producer = producer;
    }

    public synchronized HttpRequest generateRequest() {
        BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/");
        BasicHttpEntity entity = new BasicHttpEntity();
        entity.setContentType(ContentType.TEXT_PLAIN.toString());
        entity.setContentLength(-1);
        entity.setChunked(true);
        request.setEntity(entity);
        return request;
    }

    public HttpHost getTarget() {
        return this.target;
    }

    public synchronized void produceContent(
            final ContentEncoder encoder, final IOControl ioctrl) throws IOException {
        this.producer.produceContent(encoder, ioctrl);
        if (encoder.isCompleted()) {
            this.producer.close();
        }
    }

    public void requestCompleted(final HttpContext context) {
    }

    public void failed(final Exception ex) {
    }

    public synchronized boolean isRepeatable() {
        return this.producer.isRepeatable();
    }

    public synchronized void resetRequest() throws IOException {
        this.producer.close();
    }

    public synchronized void close() throws IOException {
        this.producer.close();
    }

}