Подтвердить что ты не робот

Предотвращение того, чтобы клиент Джерси вызывал ошибку outofmemory при публикации больших файлов

При размещении больших файлов в качестве InputStream с помощью Jersey клиент обнаруживает, что все содержимое файла буферизуется в память перед отправкой на сервер. Это вызывает проблему с большими файлами, поскольку JVM заканчивается из кучи. Как предотвратить такое поведение в клиенте в Джерси? Методы ресурсов JAX-RS на стороне сервера, похоже, не имеют этой проблемы при отправке данных.

Например:

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

Ответ 1

Чтобы предотвратить это поведение, вам нужно настроить клиент Джерси для использования chunked encoding 1 для запроса. Это устраняет необходимость установки заголовка Content-Length и будет передавать поток из входящего InputStream без буферизации всего содержимого в памяти.

По умолчанию Джерси использует класс JDK HttpURLConection для обработки запросов и ответов HTTP. К сожалению, это связано с некоторыми ошибками, связанными с передачей кодированных каналов. К счастью, у Джерси есть точки расширения, чтобы можно было использовать различные реализации HTTP-клиента. Одна такая реализация основана на Apache Http Client 2.

Существуют две реализации обработчика клиента apache htpp, одна из которых поддерживает версию 3.x версии 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>

Затем вам нужно инициализировать ваш клиент в Джерси, чтобы использовать новую реализацию:

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.