0

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

我找不到如何做到这一点。

两种类型的连接之间的主要区别是无法使用通常的但固有的阻塞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

4

1 回答 1

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();
    }

}
于 2014-07-13T14:09:55.657 回答