【问题标题】:HttpClient: disabling chunked encodingHttpClient:禁用分块编码
【发布时间】:2011-10-11 04:59:06
【问题描述】:
我正在使用 Apache Commons HttpClient 和 Restlet 来调用 Restful Web 服务。不幸的是,我的服务器(基于 Ruby on Rails)不喜欢 HttpClient 默认使用的Transfer-Encoding: chunked。
有什么方法可以禁止客户端对 POST 使用分块编码?
【问题讨论】:
标签:
java
http
restlet
apache-commons-httpclient
【解决方案1】:
作为一般规则,对于不被分块的请求,您需要指定帖子正文的确切大小,对于动态生成的数据,这意味着您需要在内存中缓冲整个响应,查看其大小,然后再发送。
Apache 客户端文档似乎证实了这一点:AbstractHttpEntity.setChunked() states
请注意,分块设置只是一个提示。如果使用 HTTP/1.0,则永远不会执行分块。否则,即使 chunked 为 false,如果实体内容长度未知(-1),HttpClient 也必须使用块编码。
【解决方案2】:
正如 Restlet 邮件列表中所说,在 Restlet 2.1 版中,您可以将 ClientResource#entityBuffering 属性设置为 true 以在内存中缓存内容并防止分块编码。
【解决方案3】:
正如@Slartibartfast 在他的回答中暗示的那样,最可靠的方法是明确将 HttpPost 切换到 HTTP 1.0 协议。
-
将 apache HttpPost 请求设置为 HTTP 1.0 协议(HttpGet 也一样,如果你需要这个......):
HttpPost httpPost = new HttpPost(someUrl);
httpPost.setProtocolVersion(HttpVersion.HTTP_1_0); // 从 Apache HttpClient v.4.3 开始
在创建 Multipart post 请求时,请提供作为附件的输入,而不是 InputStream(对于 HTTP 1.1,这会导致分块编码),而是一个字节数组,您必须事先从同一个流中创建。这就是内容长度已知的原因。参见 org.apache.http.entity.mime.MultipartEntityBuilder.addBinaryBody(String, byte[], ContentType, String)
我为 Android 开发测试了这个,需要稍微不同的类名...(请参阅 https://github.com/andstatus/andstatus/issues/249)