【问题标题】:How to use Apache AyncHttpClient to send chunked requests如何使用 Apache AyncHttpClient 发送分块请求
【发布时间】:2014-07-12 13:29:42
【问题描述】:
我希望发送一个请求正文,一次生成一个正文,但事先不知道整个长度。换句话说,我需要发送一个分块的请求。
我找不到怎么做。
两种类型的连接之间的主要区别是无法使用通常但固有地阻塞 java.io.InputStream 和 java.io.OutputStream 类来表示入站和出站内容流。 HttpCore NIO 提供ContentEncoder 和ContentDecoder 接口来处理异步内容传输的过程。
...
非阻塞 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 发送流式分块请求?
【问题讨论】:
标签:
httprequest
apache-httpclient-4.x
chunked
【解决方案1】:
您可以使用提供的HttpAsyncContentProducer 之一实现自定义HttpAsyncRequestProducer 并使其流出内容或实现您自己的内容生成逻辑
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();
}
}