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

Загрузка файлов с помощью Spring Boot

Автор оригинала: 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 .