为了防止这种行为,您需要将 Jersey 客户端配置为对请求使用分块编码1 。这消除了设置 Content-Length 标头的需要,并且将从提供的 InputStream 流式传输,而无需缓冲内存中的全部内容。
默认情况下,Jersey 使用 JDK 的 HttpURLConection 类来处理 HTTP 请求和响应。不幸的是,这有一些与分块编码传输相关的错误。幸运的是,Jersey 有扩展点以允许使用不同的 HTTP 客户端实现。一种这样的实现是基于 Apache Http Client 2的。
存在两种 apache htpp 客户端处理程序实现,一种支持现已停产的 3.x 版本,另一种使用较新的 4.x 版本。对于我们的项目,我们使用了基于旧 (3.1) 版本的实现。该库在 Maven Central 中的“contribs”子组下可用。
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-apache-client</artifactId>
<version>1.14</version>
</dependency>
接下来你必须初始化你的 Jersey 客户端以使用新的实现:
Client jerseyClient = ApacheHttpClient.create(getClientConfig());
为了启用分块编码,您必须在客户端配置上设置分块编码大小,因为默认情况下未启用它:
private ClientConfig getClientConfig() {
ClientConfig config = new DefaultClientConfig();
config.getProperties().put(
DefaultApacheHttpClientConfig.PROPERTY_CHUNKED_ENCODING_SIZE, 0);
return config;
}
只要这个属性不是null
,就会使用分块编码。事实上,1.14 版忽略了编码大小,因为底层 apache commons-httpclient 库不支持指定大小。