Как переместить большие файлы с помощью RestTemplate?

У меня есть вызов веб-службы, через который можно загружать zip-файлы. Затем файлы перенаправляются в другую службу для хранения, распаковки и т. Д. На данный момент файл хранится в файловой системе, затем создается файл FileSystemResource.

Resource zipFile = new FileSystemResource(tempFile.getAbsolutePath()); 

Я мог бы использовать ByteStreamResource, чтобы сэкономить время (сохранение файла на диске не требуется перед пересылкой), но для этого мне нужно построить массив байтов. В случае больших файлов я получу ошибку «OutOfMemory: java heap space».

 ByteArrayResource r = new ByteArrayResource(inputStream.getBytes()); 

Любые решения для пересылки файлов без получения ошибки OutOfMemory с помощью RestTemplate?

Вы можете использовать execute для этого типа операции низкого уровня. В этом fragmentе я использовал метод копирования Commons IO для копирования входного streamа. Вам нужно будет настроить HttpMessageConverterExtractor для того типа ответа, который вы ожидаете.

 final InputStream fis = new FileInputStream(new File("c:\\autoexec.bat")); // or whatever final RequestCallback requestCallback = new RequestCallback() { @Override public void doWithRequest(final ClientHttpRequest request) throws IOException { request.getHeaders().add("Content-type", "application/octet-stream"); IOUtils.copy(fis, request.getBody()); } }; final RestTemplate restTemplate = new RestTemplate(); SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); requestFactory.setBufferRequestBody(false); restTemplate.setRequestFactory(requestFactory); final HttpMessageConverterExtractor responseExtractor = new HttpMessageConverterExtractor(String.class, restTemplate.getMessageConverters()); restTemplate.execute("http://localhost:4000", HttpMethod.POST, requestCallback, responseExtractor); 

(Спасибо Baz за указание, что вам нужно вызвать setBufferRequestBody(false) или он победит точку)

Я думаю, что вышеупомянутый ответ имеет ненужный код – вам не нужно создавать анонимный внутренний class RequestCallback, и вам не нужно использовать IOUtils из apache.

Я потратил немного времени на изучение аналогичного решения для вас, и это то, что я придумал:

Вы можете значительно упростить свою задачу, используя интерфейс Spring Resource и RestTemplate.

 RestTemplate restTemplate = new RestTemplate(); SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); requestFactory.setBufferRequestBody(false); restTemplate.setRequestFactory(requestFactory); File file = new File("/whatever"); HttpEntity requestEntity = new HttpEntity<>(new FileSystemResource(file)); ResponseEntity e = restTemplate.exchange("http://localhost:4000", HttpMethod.POST, requestEntity, Map.class); 

(В этом примере предполагается, что ответ от того, где вы выполняете POSTING, – это JSON. Но это можно легко изменить, изменив class возвращаемого типа … установите на Map.class выше)

Единственная часть ответа @ artbristol, в которой вы действительно нуждаетесь, – это (которую вы можете настроить как Spring Spring).

 final RestTemplate restTemplate = new RestTemplate(); SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); requestFactory.setBufferRequestBody(false); restTemplate.setRequestFactory(requestFactory); 

После этого, я думаю, просто использование FileSystemResource как тело запроса будет правильно.

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

В моем случае мы имели gzipped наши файлы и завернули GZipInputStream в InputStreamResource .

  • сеансы загрузки исключений из постоянного хранилища
  • Как правильно использовать PagedResourcesAssembler из Spring Data?
  • Загрузка многостраничного файла с использованием шаблона Spring Rest + Spring Web MVC
  • Spring MVC - HttpMediaTypeNotAcceptableException
  • Могу ли я установить TTL для @Cacheable
  • Избегайте сериализации jacksonа на непривлекательных ленивых объектах
  • @Autowired bean имеет значение null при ссылке в конструкторе другого компонента
  • Spring MVC - привязка поля даты
  • Весенний спящий шаблон, когда использовать и почему?
  • Spring-Data FETCH JOIN with Paging не работает
  • Если вы настроили свойства подключения к базе данных в файле server.xml или context.xml
  • Давайте будем гением компьютера.