Changing the file size limit (maxUploadSize) depending on the controller

I have a Spring MVC website with two different pages that have different forms for uploading different files. One of them should have a 2 MB limit, and the other should have a 50 MB limit.

Right now, I have this limitation in my app-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> 

And I could solve the maxUploadSize exception in my main controller as follows:

 @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; } 

But this obviously only controls a 2 MB limit. How can I make a limit for 20 MB of one? I have tried this solution: https://stackoverflow.com/a/166269/2126 which updates the constraint at runtime. However, this updates it for each session and each controller. So, if one user uploads a file for the first form, another using the load in the second form must have a restriction of the first ...

Any help? thanks

+13
java spring-mvc upload
source share
5 answers

This may not seem like the best solution at first glance, but it depends on your requirements.

You can set the global option with the maximum load size for all controllers and override it with a lower value for specific controllers.

file application.properties (Spring Download)

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

Download controller with verification

 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); } 

In the case of a file larger than 2 MB, you will receive this exception in the log:

 org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size of 2097152 bytes exceeded 
+5
source share

Here's how it works: override the DispatcherServlet class. An example would probably look like this:

 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); } } 

Assuming you have configured multiple MultipartResolvers in your context application (supposedly called "resolver1" and "resolver2" in the sample code).

Of course, when you configure DispatcherServlet in your web.xml , you use this class instead of Spring DispatcherServlet .

Another way: MultipartFilter can also be used. Just override the lookupMultipartResolver method (HttpServletRequest request) and find the required resolver yourself. However, there are some ifs and buts to this. Before you use this, review the documentation.

+3
source share

Here's an elegant Spring Boot solution : ClassNotFoundException when setting maxUploadSize for CommonMultipartResolver

you can change your application application.properties to change the maximum download size as you want

0
source share
 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); } } } 
0
source share

As the main author and maintainer of Commons Fileupload, I would suggest the following regarding your use case:

  • There are two instances of FileUploadBase, one with a maximum size of 2 MB, and the other with 20 MB. Depending on the details of the request (for example, looking at the URI), use one or the other instance.
  • If you are not using FileUpload directly (but Spring, Struts, or something else to come), then most likely you will not have enough changes to Fileupload, because Frontend will not support a possible new feature, at least not initially. In this case, I suggest that you push the web interface developers to support your requirements. They can easily do this by creating an instance of FileUploadBase for each request. (This is a lightweight object if you are not using file trackers or similar advanced features, so there is no problem with that.)
  • I am ready to consider and possibly accept patches made by you or others who replace the current maxUploadSize check with a predicate or something similar.

Jochen

0
source share

All Articles