java - 防止 Jersey 客户端在发布大文件时导致内存不足错误

标签 java rest jersey jax-rs

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

例如:

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

最佳答案

为了防止这种行为,您需要将 Jersey 客户端配置为使用分 block 编码 1对于请求。这消除了设置 Content-Length header 的需要,并且将从提供的 InputStream 流式传输,而无需在内存中缓冲整个内容。

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

存在两种 apache htpp 客户端处理程序的实现,一种支持现已停产的 3.x 版本,另一种使用较新的 4.x 版本。对于我们的项目,我们使用了基于旧 (3.1) 版本的实现。该库位于 Maven Central 的“贡献”子组下。

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

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

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

为了启用分 block 编码,您必须在客户端配置中设置分 block 编码大小,因为它默认情况下未启用:

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

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

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

关于java - 防止 Jersey 客户端在发布大文件时导致内存不足错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11176824/

相关文章:

python - 如何将一个字段显示为序列化器中的字符串?

c# - 在C#中反序列化JSON数据的好方法

http - 分布式 REST 队列的可用实现

java - Jersey:返回 204 状态而不是 500

java - 如何更改 Jersey EventInput 使用的分隔符

Java文件路径问题

Java:创建其构造函数可能引发异常的静态类成员

java - LocalDateTime , ZonedDateTime 和时间戳

java - 将代码分离到不同的类 [Java]

servlets - Servlet 过滤器和 Jersey 过滤器有什么区别?