java HttpClient:禁用分块编码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7721554/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
HttpClient: disabling chunked encoding
提问by Thilo-Alexander Ginkel
I am using the Apache Commons HttpClient along with Restlet to call a restful web service. Unfortunately, my server (based on Ruby on Rails) does not like the Transfer-Encoding: chunked
that HttpClient is using by default.
我正在使用 Apache Commons HttpClient 和 Restlet 来调用一个安静的 Web 服务。不幸的是,我的服务器(基于 Ruby on Rails)不喜欢Transfer-Encoding: chunked
HttpClient 默认使用的。
Is there any way to disable the usage of chunked encoding for POSTs from the client?
有什么方法可以禁用对来自客户端的 POST 使用分块编码吗?
回答by Slartibartfast
As a general rule, for request not to be chunked, you need to specify exact size of post body, which for dynamically generated data means you need to buffer entire response in memory, see its size and only then send it.
作为一般规则,对于不分块的请求,您需要指定帖子正文的确切大小,这对于动态生成的数据意味着您需要在内存中缓冲整个响应,查看其大小然后才发送它。
Apache client documentation seems to confirm this: AbstractHttpEntity.setChunked()
states
Apache 客户端文档似乎证实了这一点:AbstractHttpEntity.setChunked()
states
Note that the chunked setting is a hint only. If using HTTP/1.0, chunking is never performed. Otherwise, even if chunked is false, HttpClient must use chunk coding if the entity content length is unknown (-1).
请注意,分块设置只是一个提示。如果使用 HTTP/1.0,则永远不会执行分块。否则,即使 chunked 为 false,如果实体内容长度未知 (-1),HttpClient 也必须使用块编码。
回答by Jerome Louvel
As said in Restlet mailing list, in Restlet version 2.1, you can set ClientResource#entityBuffering property to true to cache content in memory and prevent chunked encoding.
正如在 Restlet 邮件列表中所说,在 Restlet 2.1 版中,您可以将 ClientResource#entityBuffering 属性设置为 true 以在内存中缓存内容并防止分块编码。
回答by yvolk
The most reliable way, as @Slartibartfast hinted in his answer, is to explicitlyswitch HttpPost to HTTP 1.0 protocol.
正如@Slartibartfast 在他的回答中暗示的那样,最可靠的方法是将HttpPost显式切换为 HTTP 1.0 协议。
Set apache HttpPost request to HTTP 1.0 protocol (the same for HttpGet, if you need this...):
HttpPost httpPost = new HttpPost(someUrl); httpPost.setProtocolVersion(HttpVersion.HTTP_1_0); // Since v.4.3 of Apache HttpClient
When creating Multipart post request provide as an input for an attachment not an InputStream (as for HTTP 1.1, which causes chunked encoding), but an array of bytes, which you have to create from the same stream beforehand. This is why content length is known. See org.apache.http.entity.mime.MultipartEntityBuilder.addBinaryBody(String, byte[], ContentType, String)
将 apache HttpPost 请求设置为 HTTP 1.0 协议(对于 HttpGet 也是如此,如果您需要的话...):
HttpPost httpPost = new HttpPost(someUrl); httpPost.setProtocolVersion(HttpVersion.HTTP_1_0); // 从 Apache HttpClient v.4.3 开始
创建多部分发布请求时,请提供作为附件的输入,而不是 InputStream(对于 HTTP 1.1,会导致分块编码),而是一个字节数组,您必须事先从同一流创建。这就是为什么内容长度是已知的。参见 org.apache.http.entity.mime.MultipartEntityBuilder.addBinaryBody(String, byte[], ContentType, String)
I tested this for Android development, that required slightly different class names... (see https://github.com/andstatus/andstatus/issues/249)
我为 Android 开发测试了这个,需要稍微不同的类名......(见https://github.com/andstatus/andstatus/issues/249)