Автор оригинала: Dhananjay Singh.
Вступление
Загрузка файлов на веб-сайт не является необычной задачей, но ее также не очень просто выполнить. Некоторые примеры использования, объясняющие, почему вы хотите загрузить файл на веб-сайт, включают сервисы, предлагающие онлайн-конвертацию файлов и веб-сайты для обмена фотографиями. В некоторых приложениях мы можем даже захотеть отправить файл другому пользователю и т. Д.
Spring предоставляет интерфейс MultipartFile
для обработки HTTP-запросов на загрузку файлов из нескольких частей. Запросы на создание составных файлов разбивают большие файлы на более мелкие фрагменты, что делает его эффективным для загрузки файлов. Более подробную информацию об этом можно найти здесь .
Настройка проекта
Чтобы продемонстрировать загрузку файлов, мы создадим типичное приложение Spring MVC , которое состоит из Контроллера
, Службы
для внутренней обработки и Thymeleaf для визуализации представления.
Самый простой способ начать со скелетного загрузочного проекта Spring, как всегда, – это использовать Spring Initializr . Выберите предпочитаемую версию Spring Boot и добавьте зависимости Web
и Thymeleaf
:
После этого сгенерируйте его как проект Maven , и все готово!
Создание приложения
Класс обслуживания
Давайте начнем с создания слоя Service
в первую очередь. Мы назовем его как FileService.java
:
@Service public class FileService { @Value("${app.upload.dir:${user.home}}") public String uploadDir; public void uploadFile(MultipartFile file) { try { Path copyLocation = Paths .get(uploadDir + File.separator + StringUtils.cleanPath(file.getOriginalFilename())); Files.copy(file.getInputStream(), copyLocation, StandardCopyOption.REPLACE_EXISTING); } catch (Exception e) { e.printStackTrace(); throw new FileStorageException("Could not store file " + file.getOriginalFilename() + ". Please try again!"); } } }
Давайте разберем это по строчкам:
@Service
является специализацией@компонента
аннотации. Это говорит Весне, что это класс обслуживания. Обычно вся бизнес-логика записывается на этом уровне.- Затем у нас есть переменная
uploadDir
, которую мы будем использовать для хранения пути к каталогу, в который мы хотим загрузить наш файл. Он снабжен аннотацией@Value
, что означает, что его значение может быть задано файломapplication.properties
с помощью ключаapp.upload.dir
. В случае, если этот ключ не определен, значением по умолчанию являетсяuser.home
, которое присутствует в переменной среды каждой операционной системы. - Затем у нас есть общедоступный метод
загрузить файл
, который принимаетСоставной файл
в качестве аргумента. - Затем мы создали полный
Путь
файла с помощью классаПути
, предоставленного Java.StringUtils.cleanPath
используется для очистки пути, и мы просто добавляемuploadDir
к нему, используяФайл.разделитель
. Всегда используйте служебные методы для обработки путей в коде, потому что они автоматически обрабатывают различные реализации ОС. Например, в Windows разделителем файлов является\
, в то время как в Linux это/
. - Затем мы копируем файл в папку с помощью
Files.copy
. ПараметрREPLACE_EXISTING
copy переопределит любой файл с тем же именем. - Если во всем этом процессе есть
Исключение
, мы его зафиксировали и создали пользовательскоеИсключение FileStorageException
исключение.
Пользовательское Исключение
Мы написали пользовательское Исключение FileStorageException
для любого исключения во время процесса загрузки файла. Это простой класс, который расширяет Исключение RuntimeException
:
public class FileStorageException extends RuntimeException { private static final long serialVersionUID = 1L; private String msg; public FileStorageException(String msg) { this.msg = msg; } public String getMsg() { return msg; } }
Чтобы иметь возможность использовать исключение так, как это сделали мы, Spring должен знать, как с ним бороться, если оно возникнет. Для этого мы создали AppExceptionHandler
, который аннотирован @ControllerAdvice
и имеет @ExceptionHandler
, определенный для FileStorageException
:
@ControllerAdvice public class AppExceptionHandler { @ExceptionHandler(FileStorageException.class) public ModelAndView handleException(FileStorageException exception, RedirectAttributes redirectAttributes) { ModelAndView mav = new ModelAndView(); mav.addObject("message", exception.getMsg()); mav.setViewName("error"); return mav; } }
В методе HandleException
мы просто вернули объект ModelAndView
, который вернет ошибку сообщение
, заданное в представлении ошибка
, которое является просто шаблоном Thymeleaf с именем error.html
:
ERROR Error!!!
Если вы хотите узнать больше об исключениях в Java и Spring, мы подробно рассмотрели это в следующих статьях:
- Обработка исключений в Java: Полное руководство с лучшими и наихудшими практиками
- Как создавать пользовательские исключения в Java
- Обработка исключений весной
Контроллер и интерфейс
Давайте теперь создадим простой Файловый контроллер
класс, который будет использовать Файловую службу
для обработки загрузки файлов:
@Controller public class FileController { @Autowired FileService fileService; @GetMapping("/") public String index() { return "upload"; } @PostMapping("/uploadFile") public String uploadFile(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes) { fileService.uploadFile(file); redirectAttributes.addFlashAttribute("message", "You successfully uploaded " + file.getOriginalFilename() + "!"); return "redirect:/"; } }
Давайте разберем это по строчкам:
@Controller
аннотация также является специализацией@Компонента
аннотации. Это заставляет класс принимать HTTP-запрос и отвечать соответствующим образом. Он также заботится о различном преобразовании полезной нагрузки запроса во внутреннюю структуру данных.- Далее мы
@Autowired
| Файловый сервискомпонент, чтобы мы могли использовать его
Метод загрузки файла.
Тогда у нас есть простое - GetMapping
в
/, которое просто вернет строку
upload. Будучи классом контроллера, Spring будет искать
upload.htmlи передайте его в браузер.
Далее, у нас есть - Сопоставление записей
файла
/загрузки, в котором есть
Параметр запроса| составного файла
, представляющий собой объект, содержащий ваш файл и его метаданные.Затем мы использовали
Файловый сервис - |/uploadFile
метод загрузки файла.
Атрибуты перенаправления- это специализация интерфейса Spring
Model, который используется для выбора атрибутов для сценария перенаправления.
Если описанная выше операция прошла успешно, мы устанавливаем сообщение об успешном выполнении вАтрибутах перенаправления
и перенаправляем на ту же страницу. -
Теперь давайте сделаем еще один шаблон Thymeleaf, upload.html
:
Spring Boot File Upload Example
Upload Single File:
Git Essentials
Ознакомьтесь с этим практическим руководством по изучению Git, содержащим лучшие практики и принятые в отрасли стандарты. Прекратите гуглить команды Git и на самом деле изучите это!
Выше у нас есть простая форма
, которая сопоставляется с /файлом загрузки
URL. Обратите внимание, что это enctype
является составными/данными формы
и ввод
введите как файл
. В нижней части есть сообщение div
для отображения сообщения об успешном выполнении.
Наш основной класс-это типичный основной класс Spring Boot:
@SpringBootApplication public class FileIoApplication { public static void main(String[] args) { SpringApplication.run(FileIoApplication.class, args); } }
Давайте запустим наше приложение и перейдем к http://localhost:8080
:
Выберите файл и загрузите, вы должны увидеть что-то вроде:
Загрузка Нескольких Файлов
Аналогично, мы можем написать код для загрузки нескольких файлов. Добавьте следующее сопоставление в FileController.java
:
@PostMapping("/uploadFiles") public String uploadFiles(@RequestParam("files") MultipartFile[] files, RedirectAttributes redirectAttributes) { Arrays.asList(files) .stream() .forEach(file -> fileService.uploadFile(file)); redirectAttributes.addFlashAttribute("message", "You successfully uploaded all files!"); return "redirect:/"; }
Как вы можете видеть, сопоставление /загрузка файлов
аналогично предыдущему, за исключением того, что в качестве аргумента используется Составной файл []
. Мы использовали поток Java 8 API для загрузки каждого файла в массив.
Как и раньше, если описанная выше операция пройдет успешно, мы установим сообщение об успехе в Атрибутах перенаправления
и перенаправим на ту же страницу.
Теперь нам просто нужно обновить код в шаблоне upload.html
чтобы справиться с этим:
Upload Multiple Files:
Единственное отличие от предыдущего HTML заключается в том, что сопоставление выполняется с конечной точкой /загрузки файлов
, а ввод
имеет атрибут несколько
, позволяющий выбрать более одного файла. Кроме того , поскольку @RequestParam
является файлами
, мы должны использовать одно и то же имя
в HTML.
Давайте снова запустим наше приложение и перейдем к http://localhost:8080
:
Выбор второго варианта теперь позволяет нам выбрать более одного файла из нашей файловой системы и загрузить их все.
Ограничение размера файла
Вы можете настроить ограничения на загрузку файлов с помощью spring.servlet.multipart.max-размер файла
и spring.servlet.multipart.max-размер запроса
в application.properties
:
spring.servlet.multipart.max-file-size = 5MB spring.servlet.multipart.max-request-size = 5MB
Вы можете установить ограничения в КБ
, МБ
, ГБ
и т.д.
Значение по умолчанию для spring.servlet.multipart.максимальный размер файла
составляет 1 МБ, а значение по умолчанию для spring.servlet.multipart.максимальный размер запроса
составляет 10 МБ. Увеличение предела для максимального размера файла
, вероятно, является хорошей идеей, так как значение по умолчанию очень низкое, но будьте осторожны, чтобы не установить его слишком высоким, что может перегрузить ваш сервер.
Вывод
В этой статье мы рассмотрели, как загрузить один файл и несколько файлов в приложение Spring Boot. Мы использовали интерфейс Spring MultipartFile
для захвата файла в шаблонах HTTP-запроса и Thymeleaf в качестве нашего движка рендеринга.
Как всегда, код для примеров, используемых в этой статье, можно найти на GitHub .