Рубрики
Без рубрики

Spring и Apache FileUpload

Краткое и практическое руководство по использованию загрузки файлов Apache с помощью Spring.

Автор оригинала: baeldung.

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 .