«1. Обзор

В среде Spring MaxUploadSizeExceededException возникает, когда приложение пытается загрузить файл, размер которого превышает определенный порог, указанный в конфигурации.

В этом уроке мы рассмотрим, как указать максимальный размер загрузки. Затем мы покажем простой контроллер загрузки файлов и обсудим различные методы обработки этого исключения.

2. Установка максимального размера загружаемых файлов

По умолчанию размер загружаемых файлов не ограничен. Чтобы установить максимальный размер загрузки, вы должны объявить bean-компонент типа MultipartResolver.

Давайте рассмотрим пример, который ограничивает размер файла до 5 МБ:

@Bean
public MultipartResolver multipartResolver() {
    CommonsMultipartResolver multipartResolver
      = new CommonsMultipartResolver();
    multipartResolver.setMaxUploadSize(5242880);
    return multipartResolver;
}

3. Контроллер загрузки файла

Далее давайте определим метод контроллера, который обрабатывает загрузку и сохранение файла на сервер:

@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public ModelAndView uploadFile(MultipartFile file) throws IOException {
 
    ModelAndView modelAndView = new ModelAndView("file");
    InputStream in = file.getInputStream();
    File currDir = new File(".");
    String path = currDir.getAbsolutePath();
    FileOutputStream f = new FileOutputStream(
      path.substring(0, path.length()-1)+ file.getOriginalFilename());
    int ch = 0;
    while ((ch = in.read()) != -1) {
        f.write(ch);
    }
    
    f.flush();
    f.close();
    
    modelAndView.getModel().put("message", "File uploaded successfully!");
    return modelAndView;
}

Если пользователь попытается загрузить файл размером более 5 МБ, приложение выдаст исключение типа MaxUploadSizeExceededException.

4. Обработка MaxUploadSizeExceededException

Чтобы обработать это исключение, мы можем реализовать в нашем контроллере интерфейс HandlerExceptionResolver или создать аннотированный класс @ControllerAdvice.

4.1. Реализация HandlerExceptionResolver

Интерфейс HandlerExceptionResolver объявляет метод с именем resolveException(), в котором могут обрабатываться исключения различных типов.

Давайте переопределим метод resolveException() для отображения сообщения в случае, если пойманное исключение имеет тип MaxUploadSizeExceededException:

@Override
public ModelAndView resolveException(
  HttpServletRequest request,
  HttpServletResponse response, 
  Object object,
  Exception exc) {   
     
    ModelAndView modelAndView = new ModelAndView("file");
    if (exc instanceof MaxUploadSizeExceededException) {
        modelAndView.getModel().put("message", "File size exceeds limit!");
    }
    return modelAndView;
}

4.2. Создание перехватчика рекомендаций контроллера

Существует несколько преимуществ обработки исключений с помощью перехватчика, а не в самом контроллере. Во-первых, мы можем применять одну и ту же логику обработки исключений к нескольким контроллерам.

Другой момент заключается в том, что мы можем создать метод, нацеленный только на то исключение, которое мы хотим обработать, позволяя фреймворку делегировать обработку исключения без необходимости использовать instanceof для проверки того, какой тип исключения был выдан:

@ControllerAdvice
public class FileUploadExceptionAdvice {
     
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public ModelAndView handleMaxSizeException(
      MaxUploadSizeExceededException exc, 
      HttpServletRequest request,
      HttpServletResponse response) {
 
        ModelAndView modelAndView = new ModelAndView("file");
        modelAndView.getModel().put("message", "File too large!");
        return modelAndView;
    }
}

5. Конфигурация Tomcat

Если вы выполняете развертывание на сервере Tomcat версии 7 и выше, существует свойство конфигурации, называемое maxSwallowSize, которое вам, возможно, придется установить или изменить.

Это свойство указывает максимальное количество байтов, которое Tomcat будет «проглатывать» для загрузки от клиента, когда он знает, что сервер проигнорирует файл.

Значение свойства по умолчанию — 2097152 (2 МБ). Если оставить без изменений или установить меньше предела в 5 МБ, который мы установили в MultipartResolver, Tomcat отклонит любую попытку загрузить файл размером более 2 МБ, и наша настраиваемая обработка исключений никогда не будет вызываться.

Для того, чтобы запрос был успешным и отображалось сообщение об ошибке от приложения, необходимо установить свойство maxSwallowSize в отрицательное значение. Это указывает Tomcat проглотить все неудачные загрузки независимо от размера файла.

Это делается в файле TOMCAT_HOME/conf/server.xml:

<Connector port="8080" protocol="HTTP/1.1"
  connectionTimeout="20000"
  redirectPort="8443" 
  maxSwallowSize = "-1"/>

6. Заключение

В этой статье мы продемонстрировали, как настроить максимальный размер загружаемого файла в Spring и как справиться с исключение MaxUploadSizeExceededException, возникающее, когда клиент пытается загрузить файл, превышающий этот предельный размер.

Полный исходный код этой статьи можно найти в проекте GitHub.