无法解析多部分servlet请求,嵌套异常为org.apache.commons.fileupload.FileUploadException
问题内容:
通过使用CommonsMultipartResolver库在Spring中上传10 MB大小的csv文件时遇到错误。我已经在xml文件Xml File
Confi中进行了以下设置:
<beans:bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- max upload size in bytes -->
<beans:property name="maxUploadSize" value="99971520" /> <!-- 99MB -->
<!-- max size of file in memory (in bytes) -->
<beans:property name="maxInMemorySize" value="1048576" /> <!-- 1MB -->
控制器代码:
@RequestMapping(value="/uploadForm",method = RequestMethod.POST)
public @ResponseBody String uploadForm1(@ModelAttribute("admin") BillingAndRecon billingandrecon,@RequestParam String id,BindingResult result,Principal principal,@RequestParam MultipartFile file,HttpSession session) throws ServiceException, DaoException, IllegalStateException, IOException {
File uploadFile = null;
String msg = "";
if (!file.getOriginalFilename().equals("")) {
logger.info("Before Multipart file get path >> ");
BillingAndReconServiceImpl asi = (BillingAndReconServiceImpl) this.billingAndReconService;// not correct!!
String uploadDirectoryPath = asi.getUploadDirectoryPath(); // not correct!!
uploadFile = new File( uploadDirectoryPath + file.getOriginalFilename());
logger.info("Before Multipart file get path uploadDirectoryPath >> "+uploadDirectoryPath);
file.transferTo(uploadFile);
}
}
表单页面:
<form:form action="./uploadForm" method="post" enctype="multipart/form-data" ModelAttribute=="admin">
<input type="file" name="file" />
<input type="text" name="id" />
</form:form>
但是我不明白什么是问题。我也尝试设置大小和设置标头enctype="multipart/form-data"
,但尚未解决。
以下是错误:
org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is org.apache.commons.fileupload.FileUploadException: the request was rejected because no multipart boundary was found] with root cause org.apache.commons.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.<init>(FileUploadBase.java:954)
at org.apache.commons.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:331)
at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:351)
at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:126)
at org.springframework.web.multipart.commons.CommonsMultipartResolver.parseRequest(CommonsMultipartResolver.java:156)
at org.springframework.web.multipart.commons.CommonsMultipartResolver.resolveMultipart(CommonsMultipartResolver.java:139)
at org.springframework.web.servlet.DispatcherServlet.checkMultipart(DispatcherServlet.java:1047)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:892)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:920)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:827)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:801)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
问题答案:
正如 @ChristianMaioliM 在评论中所要求的那样,添加了有关以下内容的更多详细信息:代码中的问题是
BindingResult参数未遵循模型对象 。
Errors或BindingResult参数必须跟随立即绑定的模型对象,因为方法签名可能具有多个模型对象,并且Spring将为它们中的每个对象创建一个单独的BindingResult实例,因此以下示例将不起作用
参考docs
BindingResult和@ModelAttribute的无效顺序
要解决此问题,请更改您的控制器方法处理程序签名,以遵循BindingResult和模型对象之间的参数顺序,例如:
从:
@RequestMapping(value="/uploadForm",method = RequestMethod.POST)
public @ResponseBody String uploadForm1(@ModelAttribute("admin") BillingAndRecon billingandrecon,@RequestParam String id,BindingResult result,Principal principal,@RequestParam MultipartFile file,HttpSession session) throws ServiceException, DaoException, IllegalStateException, IOException {
至:
@RequestMapping(value="/uploadForm",method = RequestMethod.POST)
public String uploadForm1(
@ModelAttribute("admin") BillingAndRecon billingandrecon,
BindingResult result,
Principal principal,
HttpSession session) throws ServiceException, DaoException, IllegalStateException, IOException {
//do file save here
return "some-view-name";
}
并在BillingAndRecon类中添加mulitpart / binding字段,例如:
public class BillingAndRecon {
private MultipartFile file;
private String id;
no-arg constructor;
getters;
setters;
}
注意: BindingResult参数应在@ModelAttrubiute/@RequestBody
和jsp形式:
<form:form action="${pageContext.request.contextPath}/uploadForm"
method="post"
enctype="multipart/form-data"
modelAttribute="admin">
<input type="file" name="file" />
<form:input path="id" />
</form:form>
并且不要忘记在GET处理程序中添加绑定实例,例如:
@RequestMapping(value="/uploadForm",method = RequestMethod.GET)
public String uploadFormView(Model model){
model.addAttribute("admin", new BillingAndRecon());
return "your-upload-view-name";
}