Important: This question is absolutely useless for any version of Spring above 3.0.4 , since the issue discussed in this thread has been fixed in this version for a long time and is no longer reproduced in future versions of Spring.
I am using Spring version 3.0.2. I need to upload multiple files using the multiple="multiple" attribute in a file browser, for example,
<input type="file" id="myFile" name="myFile" multiple="multiple"/>
(and not using multiple file browsers like the one indicated by this answer , it really works, I tried).
Although no version of Internet Explorer supports this approach, unless the appropriate jQuery plugin / widget is used, I donβt care what most other browsers do.
This works fine with file loading , but in addition to the RequestMethod.POST and RequestMethod.GET methods, I also want to use other request methods supported and suggested by Spring as RequestMethod.PUT and RequestMethod.DELETE in their respective places. For this, I configured Spring with a HiddenHttpMethodFilter , which is great for the question this indicates.
but it can only upload one file at a time , even if multiple files are selected in the file browser. In the Spring controller class, the method is displayed as follows.
@RequestMapping(method={RequestMethod.POST}, value={"admin_side/Temp"}) public String onSubmit(@RequestParam("myFile") List<MultipartFile> 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()); } }
Even with the request parameter @RequestParam("myFile") List<MultipartFile> files , which is a List type MultipartFile (it can always only have one file at a time).
I could find a strategy that is likely to work with multiple files on this blog . I carefully studied it.
The solution below in DECISION 2 - USING THE RAW REQUEST says:
If, however, the client insists on using the same form input name as βfiles []β or βfilesβ, and then filling this name with several files, then a little hack is required, as follows . As noted above, Spring2.5 throws an exception if it detects the same input name of a file type of a type more than once. CommonsFileUploadSupport - the class that throws this exception is not final, and the method that throws this exception is protected in such a way that using miracles of inheritance and subclasses of one can just fix / change the logic a little as follows . Ive changed literally one word, representing one invocation method which allows us to have several files included in the same login form.
He is trying to override the method
protected MultipartParsingResult parseFileItems(List fileItems, String encoding){}
of the abstract CommonsFileUploadSupport class, extending the CommonsMultipartResolver class, for example,
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<String, MultipartFile> multipartFiles = new HashMap<String, MultipartFile>(); Map multipartParameters = new HashMap();
What happens is that the last line in the parseFileItems() method (return statement) i.e.
return new MultipartParsingResult(multipartFiles, multipartParameters);
causes a compile-time error because the first parameter multipartFiles is a Map type implemented by HashMap , but in fact it requires a parameter of type MultiValueMap<String, MultipartFile>
This is the constructor of the static class inside the CommonsFileUploadSupport abstract class,
public abstract class CommonsFileUploadSupport { protected static class MultipartParsingResult { public MultipartParsingResult(MultiValueMap<String, MultipartFile> mpFiles, Map<String, String[]> mpParams) {} } }
The reason may be - this solution applies to Spring version 2.5, and I'm using Spring version 3.0.2, which may not be acceptable for this version.
I tried replacing Map with MultiValueMap various ways, such as shown in the next code segment,
MultiValueMap<String, MultipartFile>mul=new LinkedMultiValueMap<String, MultipartFile>(); for(Entry<String, MultipartFile>entry:multipartFiles.entrySet()) { mul.add(entry.getKey(), entry.getValue()); } return new MultipartParsingResult(mul, multipartParameters);
but without success. I'm not sure how to replace Map with MultiValueMap , and even this may work. After that, the browser shows the Http response,
HTTP Status 400
enter status report
message
description The request sent by the client was syntactically incorrect ().
Apache Tomcat / 6.0.26
I tried to shorten the question as soon as possible, and I did not include the extra code.
How was it possible to upload multiple files after Spring was configured using HiddenHttpMethodFilter ?
This blog indicates that this is a long-term, high-priority error.
If there is no solution regarding version 3.0.2 (3 or higher), then I need to disable Spring support forever and continue to use commons-fileupolad , as suggested by the third solution on this blog, permanently losing PUT, DELETE and other query methods.
Very few code changes in the parseFileItems() method inside the MultiCommonsMultipartResolver class can lead to loading multiple files, but I could not succeed in my attempts (again with Spring version 3.0.2 (3 or higher)).