Java клиент Джерси - загрузка файла 1 ГБ с 256 МБ кучи JVM клиента - PullRequest
1 голос
/ 30 марта 2020

Я использую Jersey 2.28 и хочу написать клиент для загрузки файлов 1 ГБ, в то время как куча JVM клиента не может go выше 256 МБ.

Какие у меня есть варианты?

Я попробовал с приведенным ниже фрагментом, но получил OOM, так как кажется, что Джерси продолжает читать столько, сколько может из InputStream. Можно ли проинструктировать Джерси о гриппе sh, чтобы иметь дело с большими входами?

public Response upload(InputStream inputStream) {
    Client client = ClientBuilder.newBuilder().build();
    client.register(MultiPartFeature.class);
    WebTarget target = client.target("http://myexample.com").path("/upload");
    Invocation.Builder builder = target.request();

    FormDataMultiPart form = new FormDataMultiPart();
    form.bodyPart(new StreamDataBodyPart("file", inputStream, "filename.zip"));

    return builder.post(Entity.entity(form, form.getMediaType()));
}

Caused by: java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:3236)
    at java.io.ByteArrayOutputStream.grow(ByteArrayOutputStream.java:118)
    at java.io.ByteArrayOutputStream.ensureCapacity(ByteArrayOutputStream.java:93)
    at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:153)
    at sun.net.www.http.PosterOutputStream.write(PosterOutputStream.java:78)
    at org.glassfish.jersey.message.internal.CommittingOutputStream.write(CommittingOutputStream.java:200)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$UnCloseableOutputStream.write(WriterInterceptorExecutor.java:276)

1 Ответ

1 голос
/ 02 апреля 2020

Решение состоит в том, чтобы добавить:

client.property(ClientProperties.REQUEST_ENTITY_PROCESSING,
                RequestEntityProcessing.CHUNKED);

ClientProperties.REQUEST_ENTITY_PROCESSING:

Свойство указывает, как объект должен сериализоваться в выходной поток с помощью Connector; если следует использовать буферизацию или объект передается в виде фрагментированного кодирования.

Значение ДОЛЖНО быть экземпляром String или значением enum RequestEntityProcessing в случае программного определения c определения свойства. Допустимые значения:

BUFFERED: объект будет буферизован, а длина контента будет отправлена ​​в заголовке Content-length.

CHUNKED: будет использовано чанкованное кодирование, и объект будет быть потоковым.

Значением по умолчанию является CHUNKED. Однако из-за ограничений некоторые Connectors могут определять другое значение по умолчанию (обычно, если кодированная часть не может должным образом поддерживаться в Connector). Эта деталь должна быть указана в Javado c этого конкретного Connector. Например, HttpUrlConnector (по умолчанию Connector) использует буферизацию в качестве режима по умолчанию.

Значение строки константы свойства конфигурации равно "jersey.config.client.request.entity.processing".

...