发布大文件时,防止Jersey客户端导致outofmemory错误 [英] Preventing the Jersey client from causing an outofmemory error when posting large files

查看:129
本文介绍了发布大文件时,防止Jersey客户端导致outofmemory错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 Jersey 客户端将大文件作为InputStream放置时,似乎文件的全部内容在被发送到服务器之前被缓冲到内存中。这会导致大文件出现问题,因为JVM的堆空间不足。如何在Jersey客户端中阻止此行为?服务器端的JAX-RS资源方法在发送数据时似乎没有这个问题。

When positing large files as an InputStream using the Jersey client, it appears that the entire contents of the file is being buffered into memory before being sent to the server. This causes a problem with large files as the JVM runs out of heap space. How do I prevent this behaviour in the Jersey client? JAX-RS resource methods on the server side don't seem to have this problem when sending data.

例如:

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


推荐答案

为了防止出现这种情况,您需要配置Jersey客户端对请求使用分块编码 1 。这消除了设置Content-Length头的需要,并且将从提供的InputStream流式传输,而不会缓冲内存中的所有内容。

In order to prevent this behaviour you need configure the Jersey client to use chunked encoding1 for the request. This removes the need to set a Content-Length header and will stream from the the supplied InputStream without buffering the entire contents in memory.

默认情况下,Jersey使用JDK的HttpURLConection类处理HTTP请求和响应。不幸的是,这有一些与分块编码传输有关的错误。幸运的是,Jersey有扩展点允许使用不同的HTTP客户端实现。其中一个实现基于Apache Http Client 2

By default Jersey uses the JDK's HttpURLConection class to handle HTTP requests and responses. Unfortunately this has some bugs related to chunked encoding transfers. Fortunately, Jersey has extension points to allow different HTTP client implementations to be used. One such implementation is based on the Apache Http Client2.

存在apache htpp客户端处理程序的两个实现,一个支持现在的生命周期结束3.x版本,另一个使用较新的4.x版本。对于我们的项目,我们使用了基于旧版本(3.1)的实现。该库可在Maven Central的'contribs'子组下使用。

Two implementations of the apache htpp client handler exist, one supports the now end of life 3.x version, the other uses the newer 4.x version. For our project we used implementation based on the older (3.1) version. The library is available in Maven Central under the 'contribs' sub-group.

<dependency>
    <groupId>com.sun.jersey.contribs</groupId>
    <artifactId>jersey-apache-client</artifactId>
    <version>1.14</version>
</dependency>

接下来,您必须初始化您的Jersey客户端以使用新的实现:

Next you have to initialise your Jersey client to use the new implementation:

Client jerseyClient = ApacheHttpClient.create(getClientConfig());

为了启用分块编码,您必须在客户端配置上设置分块编码大小因为默认情况下没有启用:

In order to enable chunked encoding, you'll have to set the chunked encoding size on the client configuration as it's not enabled by default:

private ClientConfig getClientConfig() {
   ClientConfig config = new DefaultClientConfig();

   config.getProperties().put(
            DefaultApacheHttpClientConfig.PROPERTY_CHUNKED_ENCODING_SIZE, 0);
   return config;
}

只要此属性不是 null ,将使用分块编码。实际上,版本1.14忽略了编码大小,因为底层apache commons-httpclient库不支持指定大小。

As long as this property is not null, chunked encoding will be used. In fact, version 1.14 ignores the encoding size as specifying a size is not supported by the underlying apache commons-httpclient library.

这篇关于发布大文件时,防止Jersey客户端导致outofmemory错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆