gpt4 book ai didi

spring - 启用 HiddenHttpMethodFilter 后使用 Spring MVC 3.0.2 上传多个文件

转载 作者:行者123 更新时间:2023-12-04 12:34:16 25 4
gpt4 key购买 nike

重要提示:这个问题对于任何高于 的 Spring 版本完全没用。 3.0.4 因为该线程中讨论的问题是 fixed在很久以前的那个版本中,并且在 Spring 的后续版本中不再可重现。

我使用的是 Spring 3.0.2 版。我需要使用 multiple="multiple" 上传多个文件文件浏览器的属性,例如,

<input type="file" id="myFile" name="myFile" multiple="multiple"/>

(并且不使用多个文件浏览器,例如 this answer 所述的浏览器,我试过确实有效)。

尽管没有任何版本的 Internet Explorer 支持这种方法,除非使用适当的 jQuery 插件/小部件,但我现在并不关心它(因为大多数其他浏览器都支持这种方法)。

这适用于 commons fileupload但除了使用 RequestMethod.POSTRequestMethod.GET方法,我还想使用 Spring 支持和建议的其他请求方法,例如 RequestMethod.PUTRequestMethod.DELETE在自己合适的地方。为此,我用 HiddenHttpMethodFilter 配置了 Spring。一切正常,如 this question表示。

但是 一次只能上传一个文件 即使在文件浏览器中选择了多个文件。在 Spring Controller 类中,一个方法映射如下。
@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());
}
}

即使使用请求参数 @RequestParam("myFile") List<MultipartFile> files这是一个 List 类型 MultipartFile (它总是一次只能有一个文件)。

我可以找到一种可能适用于多个文件的策略 on this blog .我仔细地经历过了。

解决方案 下面 解决方案 2 – 使用原始请求部分说,

If however 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. As noted above Spring 2.5 throws an exception if it detects the same form input name of type file more than once. CommonsFileUploadSupportthe class which throws that exception is not final and the method 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. 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.



它试图覆盖该方法
protected MultipartParsingResult parseFileItems(List fileItems, String encoding){}

抽象类 CommonsFileUploadSupport 通过扩展类 CommonsMultipartResolver 如,
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);
}
}

发生的是方法中的最后一行 parseFileItems() (返回语句)即
return new MultipartParsingResult(multipartFiles, multipartParameters);

导致编译时错误,因为第一个参数 multipartFiles Map 的类型由 HashMap 实现 但实际上,它需要一个 类型的参数 MultiValueMap<String, MultipartFile>
它是抽象类中静态类的构造函数 CommonsFileUploadSupport ,
public abstract class CommonsFileUploadSupport {
protected static class MultipartParsingResult {
public MultipartParsingResult(MultiValueMap<String, MultipartFile> mpFiles, Map<String, String[]> mpParams) {}
}
}

原因可能是 - 这个解决方案是关于 Spring 2.5 版的,我使用的是 Spring 3.0.2 版,这可能不适合这个版本。

然而,我试图更换 Map MultiValueMap 以各种方式,例如以下代码段中所示的方式,
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);

但没有成功。我不知道如何更换 Map MultiValueMap 甚至这样做也可以。执行此操作后,浏览器会显示 Http 响应,

HTTP Status 400 -

type Status report

message

description The request sent by the client was syntactically incorrect ().

Apache Tomcat/6.0.26



我试图尽可能缩短问题,但我没有包含不必要的代码。

HiddenHttpMethodFilter 配置 Spring 后如何使上传多个文件成为可能?

该博客表明这是一个长期存在的高优先级错误。

如果没有关于版本 3.0.2(3 或更高版本)的解决方案,那么我必须永远禁用 Spring 支持并继续使用 commons-fileupolad正如该博客上的第三个解决方案所建议的那样,永远省略 PUT、DELETE 和其他请求方法。
parseFileItems() 中的代码改动很小类中的方法 MultiCommonsMultipartResolver可能会使其上传多个文件,但我的尝试无法成功(再次使用 Spring 版本 3.0.2(3 或更高版本))。

最佳答案

为了在一个请求中上传多个文件,我使用了以下代码:

我有这样的jsp:

<p>Select files to upload. Press Add button to add more file inputs.</p>
<table>
<tr>
<td><input name="files" type="file" multiple="true"/></td>
</tr>
<tr>
<td><input name="files" type="file" multiple="true"/></td>
</tr>
</table>
<br/><input type="submit" value="Upload" />

文件上传类bean:
import org.springframework.web.multipart.commons.CommonsMultipartFile;

public class FileUploadForm {

private CommonsMultipartFile [] files;

public CommonsMultipartFile[] getFiles() {
return files;
}

public void setFiles( CommonsMultipartFile[] files ) {
this.files = files;
}
}

Controller :
@Controller
@RequestMapping("/upload")
public class FileUploadController {

@RequestMapping(method = RequestMethod.GET)
public String displayForm(ModelMap modelMap) {
modelMap.addAttribute( new FileUploadForm() );
return "uploadForm.jsp";
}

@RequestMapping(method = RequestMethod.POST)
public String save(FileUploadForm uploadForm) {
CommonsMultipartFile[] files = uploadForm.getFiles();
if(files != null && files.length != 0) {
for(MultipartFile file : files) {
System.out.println( file.getOriginalFilename() );
}
}
return "success.jsp";
}
}

此代码允许在一个请求中上传多个文件,
并且有可能得到 CommonsMultipartFile的实例对于每个文件。

关于spring - 启用 HiddenHttpMethodFilter 后使用 Spring MVC 3.0.2 上传多个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13686757/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com