我正在使用 Apache Commons HttpClient 和 Restlet 来调用一个安静的 Web 服务。不幸的是,我的服务器(基于 Ruby on Rails)不喜欢Transfer-Encoding: chunked
HttpClient 默认使用的。
有什么方法可以禁用客户端对 POST 的分块编码的使用?
我正在使用 Apache Commons HttpClient 和 Restlet 来调用一个安静的 Web 服务。不幸的是,我的服务器(基于 Ruby on Rails)不喜欢Transfer-Encoding: chunked
HttpClient 默认使用的。
有什么方法可以禁用客户端对 POST 的分块编码的使用?
作为一般规则,对于不分块的请求,您需要指定 post body 的确切大小,对于动态生成的数据,这意味着您需要在内存中缓冲整个响应,查看其大小,然后才发送它。
Apache 客户端文档似乎证实了这一点AbstractHttpEntity.setChunked()
:
请注意,分块设置只是一个提示。如果使用 HTTP/1.0,则永远不会执行分块。否则,即使 chunked 为 false,如果实体内容长度未知 (-1),HttpClient 也必须使用块编码。
正如 Restlet 邮件列表中所说,在 Restlet 2.1 版中,您可以将 ClientResource#entityBuffering 属性设置为 true 以在内存中缓存内容并防止分块编码。
正如@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)