1. Обзор
Библиотека загрузки файлов Apache Commons помогает нам загружать большие файлы по протоколу HTTP с использованием типа multipart/form-data content.
В этом кратком руководстве мы рассмотрим, как интегрировать его с Spring.
2. Зависимости Maven
Чтобы использовать библиотеку, нам понадобится commons-fileupload артефакт:
commons-fileupload commons-fileupload 1.4
Последнюю версию можно найти на Maven Central .
3. Передача всех сразу
В демонстрационных целях мы собираемся создать Контроллер обработки запросов с полезной нагрузкой файла:
@PostMapping("/upload") public String handleUpload(HttpServletRequest request) throws Exception { boolean isMultipart = ServletFileUpload.isMultipartContent(request); DiskFileItemFactory factory = new DiskFileItemFactory(); factory.setRepository( new File(System.getProperty("java.io.tmpdir"))); factory.setSizeThreshold( DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD); factory.setFileCleaningTracker(null); ServletFileUpload upload = new ServletFileUpload(factory); List items = upload.parseRequest(request); Iterator iter = items.iterator(); while (iter.hasNext()) { FileItem item = iter.next(); if (!item.isFormField()) { try ( InputStream uploadedStream = item.getInputStream(); OutputStream out = new FileOutputStream("file.mov");) { IOUtils.copy(uploadedStream, out); } } } return "success!"; }
В начале нам нужно проверить, содержит ли запрос составное содержимое , используя метод isMultipartContent , найденный в классе ServletFileUpload из библиотеки.
По умолчанию в Spring есть MultipartResolver , который нам нужно отключить, чтобы использовать эту библиотеку. В противном случае он прочитает содержимое запроса до того, как он достигнет нашего Контроллера.
Мы можем добиться этого, включив эту конфигурацию в наш файл application.properties :
spring.http.multipart.enabled=false
Теперь мы можем установить каталог, в котором будут сохранены наши файлы, порог, в котором библиотека решит записать на диск, и если файлы должны быть удалены после завершения запроса.
Библиотека предоставляет класс DiskFileItemFactory , который берет на себя ответственность за конфигурацию для сохранения и очистки файлов . Метод setRepository задает целевой каталог, в примере показано значение по умолчанию.
Затем setSizeThreshold устанавливает максимальный размер файла.
Затем у нас есть метод setFileCleaningTracker , который при значении null оставляет временные файлы нетронутыми. По умолчанию он удаляет их после завершения запроса .
Теперь мы можем перейти к фактической обработке файлов.
Сначала мы создаем наш ServletFileUpload , включая нашу ранее созданную фабрику; затем мы приступаем к анализу запроса и генерируем список FileItem , которые являются основной абстракцией библиотеки для полей формы.
Теперь, если мы знаем, что это не обычное поле формы, мы приступаем к извлечению InputStream и вызову полезного метода копирования из IOUtils (для получения дополнительных опций вы можете ознакомиться с этим учебником) .
Теперь наш файл хранится в нужной папке. Обычно это более удобный способ справиться с этой ситуацией, поскольку он обеспечивает легкий доступ к файлам, но также не является оптимальным по времени/памяти.
В следующем разделе мы рассмотрим потоковый API.
4. Потоковое API
Потоковый API прост в использовании, что делает его отличным способом обработки больших файлов, просто не копируя во временное место:
ServletFileUpload upload = new ServletFileUpload(); FileItemIterator iterStream = upload.getItemIterator(request); while (iterStream.hasNext()) { FileItemStream item = iterStream.next(); String name = item.getFieldName(); InputStream stream = item.openStream(); if (!item.isFormField()) { // Process the InputStream } else { String formFieldValue = Streams.asString(stream); } }
В предыдущем фрагменте кода мы видим, что мы больше не включаем DiskFileItemFactory . Это происходит потому, что при использовании потокового API он нам не нужен .
Далее, для обработки полей библиотека предоставляет FileItemIterator , который ничего не читает , пока мы не извлекем их из запроса с помощью метода next .
Наконец, мы можем увидеть, как получить значения других полей формы.
5. Заключение
В этой статье мы рассмотрели, как мы можем использовать библиотеку загрузки файлов Apache Commons с Spring для загрузки и обработки больших файлов.
Как всегда, полный исходный код можно найти на GitHub .