File upload works under Jetty, but not under Tomcat

I have a web application with spring in which I am doing a file upload. Under eclipse, using Jetty (maven plugin), it works great. But when I deploy the application under Tomcat, it is not, and I get the following exception:

org.springframework.web.bind.MissingServletRequestParameterException: Required org.springframework.web.multipart.MultipartFile parameter 'file' is not present org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.raiseMissingParameterException(AnnotationMethodHandlerAdapter.java:545) org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveRequestParam(HandlerMethodInvoker.java:336) org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveHandlerArguments(HandlerMethodInvoker.java:207) org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:132) org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:326) org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:313) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875) 

Here is my form:

 <form method="post" action="../admin/import.html" id="import" enctype="multipart/form-data"> <div id="importInmates" align="center"> <input type="file" name="file" id="file" data-dojo-type="dijit.form.Button" label="<fmt:message key='import.file' />" /> <button data-dojo-type="dijit.form.Button" id="importInmates" type="submit"> <fmt:message key="import.import" /> </button> </div> <input type="hidden" name="importType" value="inmates" /> </form> 

And here is the interception method:

  @RequestMapping(value = IMPORT_PAGE, method = RequestMethod.POST) public String recieveFile(@RequestParam("importType") String importType, @RequestParam("file") MultipartFile multipartFile, final HttpSession session) { if (multipartFile.getSize() < 0) { LOGGER.debug("No file has been uploaded"); return "redirect:.." + IMPORT_PAGE; } File file = new File("tmp"); try { multipartFile.transferTo(file); BufferedReader lec = new BufferedReader(new FileReader(file)); LOGGER.debug(lec.readLine()); lec.close(); } catch (Exception e) { LOGGER.error("An exception occured while reading " + importType + " file", e); } return "redirect:.." + IMPORT_PAGE; } 

I added the following bean:

 <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="100000000"></property> </bean> 

both in applicationContext.xml and in mvc-servlet.xml, even if I think that only the latter is important.

Any help would be appreciated.

Thanks.

+4
source share
2 answers

Thanks to @Bart, I was able to find the following simple solution:

In the interception method, use @ModelAttribute instead of @RequestParam:

 @RequestMapping(value = IMPORT_PAGE, method = RequestMethod.POST) public String recieveFile(@RequestParam("importType") String importType, @ModelAttribute("file") UploadedFile uploadedFile, final HttpSession session) { MultipartFile multipartFile = uploadedFile.getFile(); 

Where UploadedFile is the following class:

 public class UploadedFile { private String type; private MultipartFile file; public String getType() { return type; } public void setType(String type) { this.type = type; } public void setFile(MultipartFile file) { this.file = file; } public MultipartFile getFile() { return file; } } 

And it works !!

Thank you all for your help.

+2
source

Use @RequestPart instead of @RequestParam .

From source:

Annotations that can be used to associate the part of the "multipart / form-data" request with the method argument. Supported types of method arguments include {@link MultipartFile} in combination with the Spring abstraction {@link MultipartResolver} {@code javax.servlet.http.Part} in combination with multiple Servlet 3.0 requests, or otherwise for any other method argument, the contents of the part transmitted via {@link HttpMessageConverter} taking into account the Content-Type header of the request part. This is similar to what @ {@ link RequestBody} makes to solve an argument based on the contents of an asymmetric regular request.

Note that the @ {@ link RequestParam} annotation can also be used for the "multipart / form-data" request part with a method argument supporting the same Method argument types. The main difference is that when the method argument is not String, @ {@ link RequestParam} relies on type conversion through the registered {@link Converter} or {@link PropertyEditor}, and @ {@ link RequestPart} relies on {@link HttpMessageConverter} s given the Content-Type header of the request part. @ {@ link RequestParam} is likely to be used with a field name-value form, while @ {@ link RequestPart} is likely to be used with parts that contain more complex content (for example, JSON, XML).

+1
source

Source: https://habr.com/ru/post/1245790/


All Articles