我使用Spring Webflow和org.springframework.web.multipart.commons.CommonsMultipartFile
从网页上传文件。当输入表单通过验证时,上传工作正常。当表单验证失败并且Web Flow尝试重新显示页面时,问题就出现了。它似乎尝试重新加载文件上传控件,它会查找上传使用的临时文件,但它不存在。查看实际的MultipartFile.java
来源,我看到了这条评论:
The temporary storages will be cleared at the end of request processing.
因此,应用程序不会重新显示网络表单,而是会抛出此错误。什么是在Web Flow中处理这个问题的最佳方法(记住Web Flow并没有给你提供与#34;常规" MVC相同的控制级别)。我可以扔掉MultipartFile对象中的任何内容,但我无法弄清楚要将其初始化为什么。
这就是我现在所得到的:
org.springframework.webflow.execution.repository.FlowExecutionRestorationFailureException: A problem occurred restoring the flow execution with key 'e1s5'
at org.springframework.webflow.execution.repository.snapshot.SerializedFlowExecutionSnapshotFactory.restoreExecution(SerializedFlowExecutionSnapshotFactory.java:82)
at org.springframework.webflow.execution.repository.snapshot.AbstractSnapshottingFlowExecutionRepository.restoreFlowExecution(AbstractSnapshottingFlowExecutionRepository.java:89)
at org.springframework.webflow.execution.repository.impl.DefaultFlowExecutionRepository.getFlowExecution(DefaultFlowExecutionRepository.java:115)
at org.springframework.webflow.executor.FlowExecutorImpl.resumeExecution(FlowExecutorImpl.java:168)
at org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handle(FlowHandlerAdapter.java:183)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
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.doGet(FrameworkServlet.java:816)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
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 net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:165)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:203)
at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:181)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
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.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1852)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: org.springframework.webflow.execution.repository.snapshot.SnapshotUnmarshalException: IOException thrown deserializing the flow execution stored in this snapshot -- this should not happen!
at org.springframework.webflow.execution.repository.snapshot.SerializedFlowExecutionSnapshot.unmarshal(SerializedFlowExecutionSnapshot.java:101)
at org.springframework.webflow.execution.repository.snapshot.SerializedFlowExecutionSnapshotFactory.restoreExecution(SerializedFlowExecutionSnapshotFactory.java:80)
... 34 more
Caused by: java.io.FileNotFoundException: C:\Users\wombat\.IntelliJIdea12\system\tomcat\Unnamed_workspace_credapp_3\work\Catalina\localhost\Application\upload_57256533_a72f_42e6_97a6_7722c4872b68_00000044.tmp (The system cannot find the file specified)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:120)
at org.apache.commons.fileupload.disk.DiskFileItem.readObject(DiskFileItem.java:663)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:969)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
at java.util.HashMap.readObject(HashMap.java:1030)
at sun.reflect.GeneratedMethodAccessor44.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:969)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
at java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:479)
at org.springframework.webflow.core.collection.LocalAttributeMap.readObject(LocalAttributeMap.java:331)
at sun.reflect.GeneratedMethodAccessor97.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:969)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
at org.springframework.webflow.engine.impl.FlowSessionImpl.readExternal(FlowSessionImpl.java:153)
at java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:1791)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1750)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
at java.util.LinkedList.readObject(LinkedList.java:964)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:969)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.readExternal(FlowExecutionImpl.java:304)
at java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:1791)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1750)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
at org.springframework.webflow.execution.repository.snapshot.SerializedFlowExecutionSnapshot.deserialize(SerializedFlowExecutionSnapshot.java:194)
at org.springframework.webflow.execution.repository.snapshot.SerializedFlowExecutionSnapshot.unmarshal(SerializedFlowExecutionSnapshot.java:99)
... 35 more
答案 0 :(得分:1)
对此的答案结果令人尴尬,甚至令人讨厌,简单。如果验证失败,请在从验证返回之前将表单对象的MultipartFile
成员设置为null。
myObject.setFileUpload(null);
当响应发送回客户端时,Spring将重新创建表单上载控件。
答案 1 :(得分:1)
而不是将MultipartFile设置为null:
myObject.setFileUpload(null);
(https://stackoverflow.com/a/22874667/7678594)
您可以在班级中将属性声明为“瞬态”:
private transient CommonsMultipartFile fileUpload;
答案 2 :(得分:0)
在数据绑定和调用验证程序之前抛出这些异常。 这可能发生 1)当您上传的文件超过配置中multipartresolver bean定义中设置的maxUploadSize并返回到验证器并访问multipartfile时。 2)由于网络延迟,请求(通过网络上传)会超时。
扩展CommonsMultipartResolver并覆盖其中的resolveMultipart方法。
public MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException {
String encoding = determineEncoding(request);
FileUpload fileUpload = prepareFileUpload(encoding);
try {
List fileItems = ((ServletFileUpload) fileUpload).parseRequest(request);
MultipartParsingResult parsingResult = parseFileItems(fileItems, encoding);
return new DefaultMultipartHttpServletRequest(
request, parsingResult.getMultipartFiles(), parsingResult.getMultipartParameters(), parsingResult.getMultipartParameterContentTypes());
} catch (FileUploadBase.SizeLimitExceededException ex) {
throw new MaxUploadSizeExceededException(fileUpload.getSizeMax(), ex);
}
catch (FileUploadException ex) {
throw new MultipartException("Could not parse multipart servlet request", ex);
}
}
如果上传仅在一个视图中,或者您可以直接进入错误页面,则使用异常解析程序: 公共类YourExceptionResolver扩展SimpleMappingExceptionResolver { @覆盖 public ModelAndView resolveException(HttpServletRequest request,HttpServletResponse response,Object handler,Exception exception){
if(exception instanceof MaxUploadSizeExceededException) {
//If (exception instanceof FileUploadBase.SizeLimitExceededException)
String errorMessage = "ERROR: Filesize exceeded.");
HashMap<String, Object> model = new HashMap<String, Object>();
model.put("errorMessage", errorMessage);
return new ModelAndView("jsp/uploadView", model);
} else {
return super.resolveException(request, response, handler, exception);
}
}