Announcement Announcement Module
Collapse
No announcement yet.
Servlet 3.0 MultipartForm parameters missing Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Servlet 3.0 MultipartForm parameters missing

    Hi!
    I'm making a simple fileupload controller, identical to http://static.springsource.org/sprin...olver-standard

    When the form is submitted I get 400 Bad request, because it cannot resolve the String parameter. When stepping through DispatcherServlet I see that the request has no multipartFiles. The underlying request._parts has two entries, one for each field.
    If I replace "org.springframework.web.multipart.support.Standar dServletMultipartResolver" with org.springframework.web.multipart.commons.CommonsM ultipartResolver everything is fine.
    In both these cases it seems like it is StandardMultipartHttpServletRequest which is instanciated.

    Another strange thing, in the non working case, is that when StandardMultipartHttpServletRequest is instanciated it finds no files in the request. part.getHeader(CONTENT_DISPOSITION) returns null, since the headers have value ".. content-disposition .." not ".. Content-Disposition .."

    Any thoughts?

  • #2
    Hi

    I have the same problems. Always get a 400 Bad request, as soon I add parameters with @RequestParam to my upload method.

    StandardMultipartHttpServletRequest
    The CONTENT_DISPOSITION is imho wrong. This should be "content-disposition" and not "Content-Disposition". I tested this on Tomcat 7.0.25 and Jetty 8.1.0 and it is in both servers written in lowercase.

    Is there already a bug report? If not I can create one.

    Comment


    • #3
      I made some more tests.

      If the controller method has a parameter @RequestParam("file") MultipartFile then you need a StandardServletMultipartResolver in the spring configuration. Unfortunately this does not work because of the bug in StandardMultipartHttpServletRequest (Content-Disposition / content-disposition)

      You can change the parameter to @RequestParam("file") Part. Then you no longer need the StandardServletMultipartResolver in your configuration. This works fine. If there is a file input element with multiple enabled (<input id="file" type="file" name="file" multiple>) this approach does not work because all files have the same name. It's no longer possible to use a parameter, but fortunately request.getParts() returns a collection of all multiparts. It's then possible to iterate over all the parts. It's important to note that not every part is a file, every form parameter is sent inside his own part. File parts should contain a filename attribute in the content-disposition header.
      A loop like this should recognize file parts

      Code:
      for (Part part : request.getParts()) {
         String fileName = getFileName(part);
         if (fileName != null) {
            //we have a file
         }
      } 
      
      private String getFileName(Part part) {
      	String partHeader = part.getHeader("content-disposition");
      
      	for (String cd : partHeader.split(";")) {
      		if (cd.trim().startsWith("filename")) {
      			return cd.substring(cd.indexOf('=') + 1).trim().replace("\"", "");
      		}
      	}
      	return null;
      }

      Then I found another problem in Jetty. According to the Servlet 3.0 specification every part with Content-Disposition, but without a filename should be available via request.getParameter. This work's in Tomcat 7.0.25, but not in Jetty 8.x

      I had this controller method and it worked fine with Tomcat but not with Jetty.
      Code:
      	public void processUpload(HttpServletRequest request, HttpServletResponse response,
      			@RequestParam("aParameter") String aParameter) {
              }
      As a workaround I removed the parameter and use this code, this work's in both servers (ByteStreams is a Google Guava class)
      Code:
        String aParameter = new String(ByteStreams.toByteArray(request.getPart("aParameter").getInputStream()))

      Comment


      • #4
        Please, open a ticket in JIRA. If it is an issue we'll try to address it soon, in the upcoming 3.1.1 maintenance release.

        Comment


        • #5
          Sorry for the delay. Was a bit busy.
          Now I did some more testing and it definitely works fine in Tomcat and Glassfish, but not with Jetty and Resin.

          >If there is a file input element with multiple enabled (<input id="file" type="file" name="file" multiple>)
          >this approach does no work because all files have the same name. It's no longer possible to use a
          >parameter, but fortunately request.getParts() returns a collection of all multiparts

          This statement from me is also totally wrong (sorry). This works fine in Tomcat and Glassfish.
          A method that handles a multiple file field looks something like this and the List contains all the selected files.

          Code:
          	@RequestMapping(value = "/uploadTest", method = RequestMethod.POST)
          	public String uploadTest(HttpServletRequest request, HttpServletResponse response,			
          			@RequestParam(value = "multipleFiles", required = false) List<MultipartFile> multipleMultipartFiles) {
                  ...
                  }

          Comment


          • #6
            I opened a ticket in Jira
            https://jira.springsource.org/browse/SPR-9149

            Comment

            Working...
            X