当大并主张作为文件使用一个InputStream 新泽西州的客户,看来该文件的全部内容被缓存到内存中被发送到服务器之前。 这会导致大型文件的问题,因为JVM上运行的堆空间不足。 如何防止在Jersey客户端这种行为? JAX-RS在服务器端资源的方法似乎并没有将数据发送到有这个问题。
例如:
WebResource dataUploadResource = buildDataUploadResource();
dataUploadResource.type(getMimeType()).put(getLargeInputStream());
为了防止这种行为,你需要配置Jersey客户端使用分块编码1的请求。 这消除了需要设置一个Content-Length头,将来自所述提供InputStream流而不在存储器中缓冲的全部内容。
默认情况下,新泽西州使用JDK的HttpURLConection类来处理HTTP请求和响应。 很不幸,这已经涉及到分块编码传输的一些错误。 幸运的是,泽西扩展点,以允许使用不同的HTTP客户端实现。 一个这样的实现是基于Apache HTTP客户端2 。
apache的HTPP客户端处理器的两种实现方式存在,一个支持现在的生活3.x版结束,另一种是使用较新的版本4.x版。 对于我们的项目,我们使用了基于旧的(3.1)版本的实现。 库中的“贡献”子组下是Maven的中央可用。
<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忽略编码大小作为指定尺寸不受底层阿帕奇公地HttpClient库支持。
文章来源: Preventing the Jersey client from causing an outofmemory error when posting large files