从张贴大文件时引起内存不足错误,导致Jersey客户端(Preventing the Jersey

2019-06-25 17:10发布

当大并主张作为文件使用一个InputStream 新泽西州的客户,看来该文件的全部内容被缓存到内存中被发送到服务器之前。 这会导致大型文件的问题,因为JVM上运行的堆空间不足。 如何防止在Jersey客户端这种行为? JAX-RS在服务器端资源的方法似乎并没有将数据发送到有这个问题。

例如:

WebResource dataUploadResource = buildDataUploadResource();
dataUploadResource.type(getMimeType()).put(getLargeInputStream());

Answer 1:

为了防止这种行为,你需要配置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