本文介绍了HiddenHttpMethodFilter启用后,使用Spring MVC 3.0.2上传多个文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 重要:对于任何高于 3.0.4 的Spring版本,这个问题是完全没有用的,因为这个线程讨论的问题是>修正了该版本,并且在Spring的后续版本中不再可用。 我使用的是Spring 3.0.2版本。我需要使用文件浏览器的 c> CommonsMultipartResolver ; 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 { $ b $ public MultiCommonsMultipartResolver(){} $ b public MultiCommonsMultipartResolver(ServletContext servletContext){ super(参数servletContext); $ b @Override @SuppressWarnings(unchecked) protected MultipartParsingResult parseFileItems(List fileItems,String encoding){ Map< String,MultipartFile> ; multipartFiles = new HashMap< String,MultipartFile>(); Map multipartParameters = new HashMap(); //提取多部分文件和多部分参数。 for(Iterator it = fileItems.iterator(); it.hasNext();){ FileItem fileItem =(FileItem)it.next(); if(fileItem.isFormField()){ String value = null; $ b $ if(encoding!= null){ try { value = fileItem.getString(encoding); } catch(UnsupportedEncodingException ex){ if(logger.isWarnEnabled()){ logger.warn(Could not decode multipart item'+ fileItem.getFieldName() +'编码'+编码+':使用平台默认); } value = fileItem.getString(); } } else { value = fileItem.getString(); String [] curParam =(String [])multipartParameters.get(fileItem.getFieldName()); if(curParam == null){ //简单表单域 multipartParameters.put(fileItem.getFieldName(),new String [] {value}); } else { //简单的表单字段数组 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){抛出new MultipartException(多个文件的字段名[+ file.getName() + ]找到 - 不支持MultipartResolver); (logger.isDebugEnabled()){ logger.debug(找到多部分文件[+ file.getName()+]大小+文件的 .getSize() +字节与原始文件名[+ file.getOriginalFilename()+],存储 + file.getStorageDescription()); 返回新的MultipartParsingResult(multipartFiles,multipartParameters); $ b $ p $ b 会发生什么事是方法的最后一行(return语句)ie $ p $返回新的MultipartParsingResult(multipartFiles ,multipartParameters); 会导致编译时错误,因为第一个参数 multipartFiles 是一种 Map 由 HashMap 但实际上,它需要一个类型为 MultiValueMap< String的参数, MultipartFile> 它是抽象类中一个静态类的构造函数 CommonsFileUploadSupport , public class MultipartParsingResult { public MultipartParsingResult(MultiValueMap< String,MultipartFile> mpFiles,Map< String,String []> mpParams){} } } 原因可能是 - 这个解决方案是关于春天版本2.5和我使用春天版本3.0.2这可能是不适合这个版本。 然而,我试图将 Map 与 MultiValueMap 以各种方式显示,如下面的代码段所示: MultiValueMap< String,MultipartFile> mul = new LinkedMultiValueMap< String,MultipartFile>(); (Entry< String,MultipartFile> entry:multipartFiles.entrySet()){ mul.add(entry.getKey(),entry.getValue()); 。 } 返回新的MultipartParsingResult(mul,multipartParameters); 但没有成功。我不知道如何取代 Map 与 MultiValueMap ,甚至可以这样做。这样做后,浏览器显示Http响应, 我试图尽可能缩短问题的可能性,而且我没有包含不必要的代码。 在Spring配置 HiddenHttpMethodFilter ? 该博客指出,这是一个长期存在的,高优先级的bug。 如果3.0版本没有解决方案。 2(3或更高),那么我必须永远禁用Spring支持,并继续使用 commons-fileupolad 正如该博客上的第三个解决方案所暗示的那样,永远省略PUT,DELETE和其他请求方法。 类 MultiCommonsMultipartResolver 中的 parseFileItems()方法中的代码可能会使其上传多个文件,但是我无法成功在我的企图(aga在Spring 3.0.2(3或更高版本)中)。解决方案问题中提到的问题是修正了自Spring 3.0.4开始。因此,如果您碰巧使用该版本或更高版本(是的,现在是4.x.x),您不需要再读这个问题/答案。Important : This question is completely useless for any Spring version higher than 3.0.4 as the issue discussed in this thread had been fixed in that version a long ago and is no longer reproducible in subsequent versions of Spring.I'm using Spring version 3.0.2. I need to upload multiple files using the multiple="multiple" attribute of a file browser such as,<input type="file" id="myFile" name="myFile" multiple="multiple"/>(and not using multiple file browsers something like the one stated by this answer, it indeed works I tried).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).This works fine with commons fileupload but in addition to using RequestMethod.POST and RequestMethod.GET methods, I also want to use other request methods supported and suggested by Spring like RequestMethod.PUT and RequestMethod.DELETE in their own appropriate places. For this to be so, I have configured Spring with HiddenHttpMethodFilter which goes fine as this question indicates.but it can upload only one file at a time even though multiple files in the file browser are chosen. In the Spring controller class, a method is mapped 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 of type MultipartFile (it can always have only one file at a time).I could find a strategy which is likely to work with multiple files on this blog. I have gone through it carefully.The solution below the section SOLUTION 2 – USE THE RAW REQUEST says,It attempts to override the method protected MultipartParsingResult parseFileItems(List fileItems, String encoding){}of the abstract class CommonsFileUploadSupport by extending the class CommonsMultipartResolver such as,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(); // 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); }}What happens is that the last line in the method parseFileItems() (the return statement) i.e.return new MultipartParsingResult(multipartFiles, multipartParameters);causes a compile-time error because the first parameter multipartFiles is a type of Map implemented by HashMap but in reality, it requires a parameter of type MultiValueMap<String, MultipartFile>It is a constructor of a static class inside the abstract class CommonsFileUploadSupport,public abstract class CommonsFileUploadSupport { protected static class MultipartParsingResult { public MultipartParsingResult(MultiValueMap<String, MultipartFile> mpFiles, Map<String, String[]> mpParams) {} }}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.I however tried to replace the Map with MultiValueMap in various ways such as the one shown in the following segment of code,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 no success. I'm not sure how to replace Map with MultiValueMap and even doing so could work either. After doing this, the browser shows the Http response,I have tried to shorten the question as possible as I could and I haven't included unnecessary code. How could be made it possible to upload multiple files after Spring has been configured with HiddenHttpMethodFilter?That blog indicates that It is a long standing, high priority bug.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 commons-fileupolad as suggested by the third solution on that blog omitting the PUT, DELETE and other request methods forever.Very little changes to the code in the parseFileItems() method inside the class MultiCommonsMultipartResolver 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)). 解决方案 The issue as mentioned in the question was fixed as of Spring 3.0.4. As such, if you happened to use that version or higher (yes, it is 4.x.x now), you would not need to read this question/answer(s) anymore. 这篇关于HiddenHttpMethodFilter启用后,使用Spring MVC 3.0.2上传多个文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
09-23 17:37