title: Uploading multiple files using Spring MVC 3.0.2 after HiddenHttpMethodFilter has been enabled
body: <p><strong>Important :</strong> This question is completely useless for any Spring version higher than <strong>3.0.4</strong> as the issue discussed in this thread had been <a href="https://jira.spring.io/browse/SPR-2784" rel="nofollow noreferrer">fixed</a> in that version a long ago and is no longer reproducible in subsequent versions of Spring.</p>
  
  <hr>
  
  <p>I'm using Spring version 3.0.2. I need to upload multiple files using the <code>multiple="multiple"</code> attribute of a file browser such as,</p>
  
  <pre><code>&lt;input type="file" id="myFile" name="myFile" multiple="multiple"/&gt;
  </code></pre>
  
  <p>(and not using multiple file browsers something like the one stated by <a href="https://stackoverflow.com/a/4241128">this answer</a>, it indeed works I tried).</p>
  
  <p>Although no versions of Internet Explorer supports this approach unless an appropriate jQuery plugin/widget is used, I don't care about it right now (since most other browsers support this).</p>
  
  <p>This works fine with <a href="http://commons.apache.org/fileupload/" rel="nofollow noreferrer">commons fileupload</a> but in addition to using <code>RequestMethod.POST</code> and <code>RequestMethod.GET</code> methods, I also want to use other request methods supported and suggested by Spring like <code>RequestMethod.PUT</code> and <code>RequestMethod.DELETE</code> in their own appropriate places. For this to be so, I have configured Spring with <a href="http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/web/filter/HiddenHttpMethodFilter.html" rel="nofollow noreferrer"><code>HiddenHttpMethodFilter</code></a> which goes fine as <a href="https://stackoverflow.com/q/13629653/1391249">this question</a> indicates.</p>
  
  <p>but <strong>it can upload only one file at a time</strong> even though multiple files in the file browser are chosen. In the Spring controller class, a method is mapped as follows.</p>
  
  <pre><code>@RequestMapping(method={RequestMethod.POST}, value={"admin_side/Temp"})
  public String onSubmit(@RequestParam("myFile") List&lt;MultipartFile&gt; files, @ModelAttribute("tempBean") TempBean tempBean, BindingResult error, Map model, HttpServletRequest request, HttpServletResponse response) throws IOException, FileUploadException {
      for (MultipartFile file : files) {
          System.out.println(file.getOriginalFilename());
      }
  }
  </code></pre>
  
  <p>Even with the request parameter <code>@RequestParam("myFile") List&lt;MultipartFile&gt; files</code> which  is a <a href="http://docs.oracle.com/javase/1.4.2/docs/api/java/util/List.html" rel="nofollow noreferrer"><code>List</code></a> of type <a href="http://static.springsource.org/spring/docs/2.0.0/api/org/springframework/web/multipart/MultipartFile.html" rel="nofollow noreferrer"><code>MultipartFile</code></a> (it can always have only one file at a time).</p>
  
  <hr>
  
  <p>I could find a strategy which is likely to work with multiple files <a href="http://dhruba.name/2008/12/27/implementing-single-and-multiple-file-multipart-uploads-using-spring-25/" rel="nofollow noreferrer">on this blog</a>. I have gone through it carefully.</p>
  
  <p>The solution <strong>below</strong> the section <em>SOLUTION 2 – USE THE RAW REQUEST</em> says,</p>
  
  <blockquote>
    <p>If however <strong>the client insists on using the same form input name such
    as ‘files[]‘ or ‘files’ and then populating that name with multiple
    files then a small hack is necessary as follows</strong>. As noted above Spring
    2.5 throws an exception if it detects the same form input name of type file more than once. <a href="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/web/multipart/commons/CommonsFileUploadSupport.html" rel="nofollow noreferrer">CommonsFileUploadSupport</a> – <strong>the class which throws
    that exception is not final and the <a href="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/web/multipart/commons/CommonsFileUploadSupport.html#parseFileItems%28java.util.List,%20java.lang.String%29" rel="nofollow noreferrer">method</a> which throws that exception
    is protected so using the wonders of inheritance and subclassing one
    can simply fix/modify the logic a little bit as follows</strong>. The change
    I’ve made is literally one word representing one method invocation
    which enables us to have multiple files incoming under the same form
    input name.</p>
  </blockquote>
  
  <p>It attempts to override the method </p>
  
  <pre><code>protected MultipartParsingResult parseFileItems(List fileItems, String encoding){}
  </code></pre>
  
  <p>of the abstract class <a href="http://static.springsource.org/spring/docs/2.5.6/api/org/springframework/web/multipart/commons/CommonsFileUploadSupport.html" rel="nofollow noreferrer"><code>CommonsFileUploadSupport</code></a> by extending the class <a href="http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/web/multipart/commons/CommonsMultipartResolver.html" rel="nofollow noreferrer"><code>CommonsMultipartResolver</code></a> such as,</p>
  
  <pre><code>package multipartResolver;
  
  import java.io.UnsupportedEncodingException;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  import javax.servlet.ServletContext;
  import org.apache.commons.fileupload.FileItem;
  import org.springframework.util.StringUtils;
  import org.springframework.web.multipart.MultipartException;
  import org.springframework.web.multipart.MultipartFile;
  import org.springframework.web.multipart.commons.CommonsMultipartFile;
  import org.springframework.web.multipart.commons.CommonsMultipartResolver;
  
  public final class MultiCommonsMultipartResolver extends CommonsMultipartResolver {
  
      public MultiCommonsMultipartResolver() {}
  
      public MultiCommonsMultipartResolver(ServletContext servletContext) {
          super(servletContext);
      }
  
      @Override
      @SuppressWarnings("unchecked")
      protected MultipartParsingResult parseFileItems(List fileItems, String encoding) {
          Map&lt;String, MultipartFile&gt; multipartFiles = new HashMap&lt;String, MultipartFile&gt;();
          Map multipartParameters = new HashMap();
  
          // Extract multipart files and multipart parameters.
          for (Iterator it = fileItems.iterator(); it.hasNext();) {
              FileItem fileItem = (FileItem) it.next();
  
              if (fileItem.isFormField()) {
                  String value = null;
  
                  if (encoding != null) {
                      try {
                          value = fileItem.getString(encoding);
                      } catch (UnsupportedEncodingException ex) {
                          if (logger.isWarnEnabled()) {
                              logger.warn("Could not decode multipart item '" + fileItem.getFieldName()
                                      + "' with encoding '" + encoding + "': using platform default");
                          }
  
                          value = fileItem.getString();
                      }
                  } else {
                      value = fileItem.getString();
                  }
  
                  String[] curParam = (String[]) multipartParameters.get(fileItem.getFieldName());
  
                  if (curParam == null) {
                      // simple form field
                      multipartParameters.put(fileItem.getFieldName(), new String[]{value});
                  } else {
                      // array of simple form fields
                      String[] newParam = StringUtils.addStringToArray(curParam, value);
                      multipartParameters.put(fileItem.getFieldName(), newParam);
                  }
              } else {
                  // multipart file field
                  CommonsMultipartFile file = new CommonsMultipartFile(fileItem);
                  if (multipartFiles.put(fileItem.getName(), file) != null) {
                      throw new MultipartException("Multiple files for field name [" + file.getName()
                              + "] found - not supported by MultipartResolver");
                  }
  
                  if (logger.isDebugEnabled()) {
                      logger.debug("Found multipart file [" + file.getName() + "] of size " + file.getSize()
                              + " bytes with original filename [" + file.getOriginalFilename() + "], stored "
                              + file.getStorageDescription());
                  }
              }
          }
  
          return new MultipartParsingResult(multipartFiles, multipartParameters);
      }
  }
  </code></pre>
  
  <p>What happens is that the last line in the method <code>parseFileItems()</code> (the return statement) i.e.</p>
  
  <pre><code>return new MultipartParsingResult(multipartFiles, multipartParameters);
  </code></pre>
  
  <p>causes a compile-time error because the first parameter <code>multipartFiles</code> is a type of <a href="http://docs.oracle.com/javase/6/docs/api/java/util/Map.html" rel="nofollow noreferrer"><code>Map</code></a> implemented by <a href="http://docs.oracle.com/javase/1.4.2/docs/api/java/util/HashMap.html" rel="nofollow noreferrer"><code>HashMap</code></a> <strong>but in reality, it requires a parameter of type</strong> <code>MultiValueMap&lt;String, MultipartFile&gt;</code></p>
  
  <p>It is a constructor of a static class inside the abstract class <a href="http://static.springsource.org/spring/docs/2.5.6/api/org/springframework/web/multipart/commons/CommonsFileUploadSupport.html" rel="nofollow noreferrer"><code>CommonsFileUploadSupport</code></a>,</p>
  
  <pre><code>public abstract class CommonsFileUploadSupport {
      protected static class MultipartParsingResult {
          public MultipartParsingResult(MultiValueMap&lt;String, MultipartFile&gt; mpFiles, Map&lt;String, String[]&gt; mpParams) {}
      }
  }
  </code></pre>
  
  <p>The reason might be - this solution is about the Spring version 2.5 and I'm using the Spring version 3.0.2 which might be inappropriate for this version.</p>
  
  <hr>
  
  <p>I however tried to replace the <a href="http://docs.oracle.com/javase/6/docs/api/java/util/Map.html" rel="nofollow noreferrer"><code>Map</code></a> with <a href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/util/MultiValueMap.html" rel="nofollow noreferrer"><code>MultiValueMap</code></a> in various ways such as the one shown in the following segment of code,</p>
  
  <pre><code>MultiValueMap&lt;String, MultipartFile&gt;mul=new LinkedMultiValueMap&lt;String, MultipartFile&gt;();   
  
  for(Entry&lt;String, MultipartFile&gt;entry:multipartFiles.entrySet()) {
      mul.add(entry.getKey(), entry.getValue());
  }
  
  return new MultipartParsingResult(mul, multipartParameters);
  </code></pre>
  
  <p>but no success. I'm not sure how to replace <a href="http://docs.oracle.com/javase/6/docs/api/java/util/Map.html" rel="nofollow noreferrer"><code>Map</code></a> with <a href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/util/MultiValueMap.html" rel="nofollow noreferrer"><code>MultiValueMap</code></a> and even doing so could work either. After doing this, the browser shows the Http response,</p>
  
  <blockquote>
    <p><strong>HTTP Status 400 -</strong></p>
    
    <p>type Status report</p>
    
    <p><strong>message</strong></p>
    
    <p>description The request sent by the client was syntactically incorrect
    (). </p>
    
    <p>Apache Tomcat/6.0.26</p>
  </blockquote>
  
  <hr>
  
  <p>I have tried to shorten the question as possible as I could and I haven't included unnecessary code. </p>
  
  <p>How could be made it possible to upload multiple files after Spring has been configured with <a href="http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/web/filter/HiddenHttpMethodFilter.html" rel="nofollow noreferrer"><code>HiddenHttpMethodFilter</code></a>?</p>
  
  <p>That blog indicates that It is a long standing, high priority bug.</p>
  
  <p>If there is no solution regarding the version 3.0.2 (3 or higher) then I have to disable Spring support forever and continue to use <a href="http://commons.apache.org/fileupload/" rel="nofollow noreferrer">commons-fileupolad</a> as suggested by the third solution on that blog omitting the PUT, DELETE and other request methods forever.</p>
  
  <hr>
  
  <p>Very little changes to the code in the <code>parseFileItems()</code> method inside the class <code>MultiCommonsMultipartResolver</code>  might make it upload multiple files but I couldn't succeed in my attempts (again with the Spring version 3.0.2 (3 or higher)).</p>