2013-05-16 3 views
8

У меня есть веб-сайт Spring MVC с двумя разными страницами, которые имеют разные формы для загрузки разных файлов. У одного из них должно быть ограничение на 2 МБ, а у другого должно быть ограничение 50 МБ.Изменение ограничения размера файла (maxUploadSize) в зависимости от контроллера

Прямо сейчас, у меня есть это ограничение в мое приложение-config.xml:

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> 
    <!-- one of the properties available; the maximum file size in bytes (2097152 B = 2 MB) --> 
    <property name="maxUploadSize" value="2097152 "/> 
</bean> 

И я мог бы разрешить исключение maxUploadSize в моем главном контроллере так:

@Override 
public @ResponseBody 
ModelAndView resolveException(HttpServletRequest arg0, 
     HttpServletResponse arg1, Object arg2, Exception exception) { 
    ModelAndView modelview = new ModelAndView(); 
     String errorMessage = ""; 
     if (exception instanceof MaxUploadSizeExceededException) { 
      errorMessage = String.format("El tamaño del fichero debe ser menor de %s", UnitConverter.convertBytesToStringRepresentation(((MaxUploadSizeExceededException) exception) 
        .getMaxUploadSize())); 

     } else { 
      errorMessage = "Unexpected error: " + exception.getMessage(); 
     } 
     saveError(arg0, errorMessage); 
     modelview = new ModelAndView(); 
     modelview.setViewName("redirect:" + getRedirectUrl()); 
    } 
    return modelview; 
} 

Но это, очевидно, контролирует только ограничение 2 МБ. Как я могу сделать ограничение для 20 МБ одного? Я пробовал это решение: https://stackoverflow.com/a/11792952/1863783, который обновляет ограничение во время выполнения. Однако это обновляет его для каждой сессии и каждого контроллера. Итак, если один пользователь загружает файл для первой формы, другой, используя загрузку во второй форме, должен иметь ограничение на первый ...

Любая помощь? спасибо

+0

проверьте это [введите ссылку здесь] (http: // stackoverflow.ком/вопросы/27061209/весна загрузки ClassNotFoundException-когда-настройка-maxuploadsize-оф-commonmult/29635044 # 29635044) –

ответ

3

Вот как это возможно: переопределить класс DispatcherServlet. Примером, вероятно lõoke как следующее:

public class CustomDispatcherServlet extends DispatcherServlet { 

    private Map<String, MultipartResolver> multipartResolvers; 

    @Override 
    protected void initStrategies(ApplicationContext context) { 
      super.initStrategies(context); 
      initMultipartResolvers(context); 
    } 

    private void initMultipartResolvers(ApplicationContext context) { 
      try { 
        multipartResolvers = new HashMap<>(context.getBeansOfType(MultipartResolver.class)); 
      } catch (NoSuchBeanDefinitionException ex) { 
        // Default is no multipart resolver. 
        this.multipartResolvers = Collections.emptyMap(); 
      } 
    } 

    @Override 
    protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException { 
      if (this.multipartResolvers.isEmpty() && this.multipartResolvers.get(0).isMultipart(request)) { 
        if (request instanceof MultipartHttpServletRequest) { 
          logger.debug("Request is already a MultipartHttpServletRequest - if not in a forward, " 
            + "this typically results from an additional MultipartFilter in web.xml"); 
        } else { 
          MultipartResolver resolver = getMultipartResolverBasedOnRequest(request); 
          return resolver.resolveMultipart(request); 
        } 
      } 
      // If not returned before: return original request. 
      return request; 
    } 

    private MultipartResolver getMultipartResolverBasedOnRequest(HttpServletRequest request) { 
      // your logic to check the request-url and choose a multipart resolver accordingly. 
      String resolverName = null; 
      if (request.getRequestURI().contains("SomePath")) { 
        resolverName = "resolver1"; 
      } else { 
        resolverName = "resolver2"; 
      } 
      return multipartResolvers.get(resolverName); 
    } 
} 

Предполагая, что вы настроили несколько MultipartResolvers в вашем прикладном контексте (предположительно названный «resolver1» и «resolver2» в примере кода).

Конечно, когда вы настраиваете DispatcherServlet в своем web.xml, вы используете этот класс вместо Spring DispatcherServlet.

Другой способ: A MultipartFilter. Просто переустановите метод lookupMultipartResolver(HttpServletRequest request) и самостоятельно найдите необходимый резольвер. Однако, есть некоторые ifs и buts к этому. Прежде чем использовать это, просмотрите документацию.

0
public class BaseDispatcherServlet extends DispatcherServlet { 
    @Override 
    protected void doService(final HttpServletRequest request, final HttpServletResponse response) { 
     CommonsMultipartResolver multipartResolver = (CommonsMultipartResolver) getMultipartResolver(); 
     if (requestURI.contains("uriWithLargeFileSize")) { 
      multipartResolver.setMaxUploadSize(100 * 100L); 
     } 
    } 
}                                                                                                        
2

Может показаться, что не самое лучшее решение на первый взгляд, но это зависит от ваших требований.

Вы можете установить глобальную опцию с максимальным размером загрузки для всех контроллеров и переопределить ее с меньшим значением для определенных контроллеров.

application.properties файл (весна загрузки)

spring.http.multipart.max-file-size=50MB 

Загрузить контроллер с проверкой

public void uploadFile(@RequestPart("file") MultipartFile file) { 
    final long limit = 2 * 1024 * 1024; // 2 MB 
    if (file.getSize() > limit) { 
     throw new MaxUploadSizeExceededException(limit); 
    } 
    StorageService.uploadFile(file); 
} 

В случае файла больше, чем 2Мб вы получите это исключение в журнале:

org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size of 2097152 bytes exceeded 
Смежные вопросы