ВС Джерси Загрузка файла OutOfMemoryError - PullRequest
0 голосов
/ 29 августа 2018

У меня есть код клиента, который работал, но по мере того, как файл становился больше, я получаю сообщение об ошибке памяти. Я попробовал оба FileDataBodyPart и StreamDataBodyPart, оба терпят неудачу с той же самой ошибкой. Это мульти часть с файлом и JSON в нем. Любая помощь приветствуется.

Ниже приведен код

public static Import importFile(Log notify, String importId, File file) throws CheckedContentException {
    InputStream fileStream = null;
    try {
        LOG.warn("Uploading file " + file.getName() + " with import id " + importId);
        JsonObject metadata = new JsonObject();
        metadata.addProperty("fileType", "xyz");
        metadata.add("fileOptions", new JsonObject());
        //
        // FileDataBodyPart filePart = new FileDataBodyPart(file.getName(), file);
        fileStream = Files.asByteSource(file).openStream();
        StreamDataBodyPart filePart = new StreamDataBodyPart("file", fileStream, file.getName());
        FormDataMultiPart multipart = new FormDataMultiPart();
        multipart.field("metadata", metadata.toString(), MediaType.APPLICATION_JSON_TYPE).bodyPart(filePart);
        //
        ClientResponse response = getNewWebResourceForImport(NEW_IMPORT_PATH, importId).type(MediaType.MULTIPART_FORM_DATA_TYPE)
                .accept(MediaType.APPLICATION_JSON_TYPE).post(ClientResponse.class, multipart);
        //
        String result = response.getEntity(String.class);
        Import imp = new Gson().fromJson(result, Import.class);
        if (response.getStatus() != 200 || StringUtils.equals(imp.getStatus(), IMPORT_FILE_UPLOAD_ERROR)) {
            throw new CheckedContentException("Failed to Import File with status " + response.getStatus() + " : " + response);
        }
        notify.warn("Finished uploading File " + file.getName() + " with id " + importId);
        return imp;
    } catch (CheckedContentException e) {
        throw e;
    } catch (Exception e) {
        throw new CheckedContentException(e);
    } finally {
        IOUtils.closeQuietly(fileStream);
    }
}
private static Builder getNewWebResourceForImport(String path, String importId) {
    Client client = Client.create();
    client.addFilter(new LoggingFilter(System.out));
    WebResource webResource = client.resource(WS_URL).path(path).path(importId).path("files");
    return webResource.header(ACCESS_TOKEN_KEY, API_ACCESS_TOKEN).header(CLIENT_SECRET_TOKEN_KEY, CLIENT_TOEKN);
}
java.lang.OutOfMemoryError
at java.io.ByteArrayOutputStream.hugeCapacity(Unknown Source)
at java.io.ByteArrayOutputStream.grow(Unknown Source)
at java.io.ByteArrayOutputStream.ensureCapacity(Unknown Source)
at java.io.ByteArrayOutputStream.write(Unknown Source)
at com.sun.jersey.api.client.filter.LoggingFilter$LoggingOutputStream.write(LoggingFilter.java:109)
at com.sun.jersey.core.util.ReaderWriter.writeTo(ReaderWriter.java:115)
at com.sun.jersey.core.provider.AbstractMessageReaderWriterProvider.writeTo(AbstractMessageReaderWriterProvider.java:76)
at com.sun.jersey.core.impl.provider.entity.InputStreamProvider.writeTo(InputStreamProvider.java:98)
at com.sun.jersey.core.impl.provider.entity.InputStreamProvider.writeTo(InputStreamProvider.java:59)
at com.sun.jersey.multipart.impl.MultiPartWriter.writeTo(MultiPartWriter.java:220)
at com.sun.jersey.multipart.impl.MultiPartWriter.writeTo(MultiPartWriter.java:73)
at com.sun.jersey.api.client.RequestWriter.writeRequestEntity(RequestWriter.java:300)
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler._invoke(URLConnectionClientHandler.java:217)
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:153)
at com.sun.jersey.api.client.filter.LoggingFilter.handle(LoggingFilter.java:217)
at com.sun.jersey.api.client.Client.handle(Client.java:652)
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:682)
at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)
at com.sun.jersey.api.client.WebResource$Builder.post(WebResource.java:570)

1 Ответ

0 голосов
/ 29 августа 2018

Решение довольно простое, мне нужно было добавить ClientConfig.PROPERTY_CHUNKED_ENCODING_SIZE и установить его.

client.setChunkedEncodingSize(32 * 1024);

Это не сработало, пока я не удалил Logging filer, так как у него не хватает памяти, я добавил его в первую очередь для отладки, но забыл об этом. И, исследуя, какой размер установить для фрагментирования, я наткнулся на эту статью, в которой была та же проблема, и решил ее так же, как и я. Жаль, что я нашел это до борьбы, надеюсь, это поможет. http://davidbuccola.blogspot.com/2009/09/configure-jersey-chunked-encoding-when.html

...