Struts FileUpload 异常处理之Processing of multipart/form-data request failed.

简介:
问题:
在使用FileUpload的过程中,有一个经常抛出异常如下:
ERROR [http-8081-Processor21] (CommonsMultipartRequestHandler.java:201) -2008-04-10 11:20:27,671 Failed to parse multipart request
org.apache.commons.fileupload.FileUploadException: Processing of multipart/form-data request failed. temp\upload__3d7cf8b_11936276cf8__7ffd_00000011.tmp (系统找不到指定的路径。)
    at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:384)
    at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:268)
    at org.apache.struts.upload.CommonsMultipartRequestHandler.handleRequest(CommonsMultipartRequestHandler.java:193)
    at org.apache.struts.util.RequestUtils.populate(RequestUtils.java:443)
    at org.apache.struts.action.RequestProcessor.processPopulate(RequestProcessor.java:804)
    at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:203)
    at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
    at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
问题分析:
在我使用Struts FileUpload时有以下几个关键部分:
  • 定义Form的Enctype属性multipart/form-data,添加<input type=file>的域;
  • 在FormBean中定义与file域名称相同、类型为FormFile的属性;
  • 在strut-config.xml定义或修改controller标记,分别设置maxFileSize=10M、bufferSize=4096、tempDir=temp、inputForward=true等属性;
  • 获得FormFile类型的属性,将字节流写入指定的文件中。
而在不超出maxFileSize的范围中有一些较大文件都不能上传成功,并抛出上述异常,在指定的tempDir目录中也不能找到相应的tmp文件。在已知的单独使用commons-fileupload时经常使用的handler是ServletFileUpload或DiskFileUpload,而在查到的资料中的解释是使用DiskFileUpload就可以解决上面的问题,那么StrutsFileUpload是怎么使用这些类来处理上传的呢?查看struts-config_1_2.dtd有一个属性是multipartClass是用来设置处理这种请求的类,默认值是CommonsMultipartRequestHandler,那么应该有其它不同的处理类,于是在"org.apache.struts.upload中找到类DiskMultipartRequestHandler。这个类的处理方式是直接在临时文件目录写临时文件。那么定义multipartClass=org.apache.struts.upload.DiskMultipartRequestHandler,则异常不再出现。
但是javadoc中明明白白的写的是在commons-fileupload以后的版本中DiskMultipartRequestHandler类将由CommonsMultipartRequestHandler替代,使用CommonsMultipartRequestHandler才是明智的选择。那么分析一下,发现后者可用的原因就应该在于后者是使用硬盘空间作为交换空间,则前者就应当是使用内存做为交换空间的,那么使用内存空间应该是有边界限制的,这个属性就是memFileSize,其默认值是256K,在上传抛出异常时使用的文件就是大于这个数字的文件,发现它对应的其实就是DiskFileItemFactory的sizeThreshold属性。而对memFileSize的解释就是上传时可以在内存中保留的文件的最大值,超出这个数字则保存在其它的介质中如硬盘。也就是说要正常使用CommonsMultipartRequestHandler类处理上传请求,可以将memFileSize定义到与maxFileSize一样大,但显而易见的是一旦有更大的上传文件需求时,就会重新遇到问题,如此大的内存开销是显然是不合理的。
按道理来讲,CommonsMultipartRequestHandler做为multipartClass默认值和下一版本的保留类,应该是可以正确的使用配置文件中定义的memFileSize属性的,那么既然在异常中有“系统找不到指定的路径”字样,那就从文件系统的路径来试着解决问题。tempDir指定的目录是temp,异常的提示应该就是找不到这个目录,从本机应用中来看这个temp就是tomcat根目录下的temp,但就是这个目录在我本机上是可以找到的,在服务器上却总是提示异常。查看struts-config_1_2.dtd,对于这个参数的解释是“指定文件上传时的临时工作目录.如果没有设置,将才用Servlet容器为web应用分配的临时工作目录”。那么在我的应用中如果不指定tempDir,这个目录就是%TOMCAT_HOME%\temp;如果指定的话,就要指定绝对路径,如“C:\\temp”。
解决方法:
1、指定multipartClass为org.apache.struts.upload.DiskMultipartRequestHandler,不推荐使用这种方式;
2、指定memFileSize与maxFileSize相同的值,用于上传文件较小的情况,这种方式其实也是一种错误的方式,不推荐;
3、指定tempDir为绝对目录;
4、如果应用服务器可以为应用分配临时目录的话,可以不指定tempDir;
5、即便tempDir指定的是相对目录,如tempDir="temp",也并不是错误的,它应该是存在于当然应用的一个相对目录。
补充:
tempDir指定的目录中可能会随着时间推移出现很多后缀为"tmp"的垃圾文件,commons-fileupload提供了一个不错的解决方法,就是把下面的代码加入到web.xml中即可。
<listener>
        <listener-class>
          org.apache.commons.fileupload.servlet.FileCleanerCleanup
        </listener-class>
</listener>
需要注意的是FileCleanerCleanup是commons-fileupload1.2以后的版本才有的类。
 
______________________________________________________
 
 
看完以上, 修改struts.xml文件
Xml代码  复制代码
  1. <!-- 临时文件存放路径 -->  
  2.     <constant name="struts.multipart.saveDir" value="D://chain/jboss-web/MyTemp/"></constant>  
有待测试验证.


本文转自chainli 51CTO博客,原文链接:http://blog.51cto.com/lichen/214252,如需转载请自行联系原作者
相关文章
|
6月前
|
应用服务中间件 Apache
springmvc中报错Request processing failed;
springmvc中报错Request processing failed;
|
2月前
|
前端开发 Java
org.springframework.web.multipart.MultipartException: Current request is not a multipart request
org.springframework.web.multipart.MultipartException: Current request is not a multipart request
60 0
|
2月前
|
Java API 开发者
【已解决】Spring Cloud Feign 上传文件,提示:the request was rejected because no multipart boundary was found的问题
【已解决】Spring Cloud Feign 上传文件,提示:the request was rejected because no multipart boundary was found的问题
320 0
poi.openxml4j.exceptions.InvalidFormatException: Package should contain a content type part [M1.13]
poi.openxml4j.exceptions.InvalidFormatException: Package should contain a content type part [M1.13]
322 0
|
6月前
|
应用服务中间件 Linux
org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; nes
org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; nes
144 0
|
6月前
|
Java
【Java报错】MultipartFile 类型文件上传 Current request is not a multipart request 问题处理(postman添加MultipartFile)
【Java报错】MultipartFile 类型文件上传 Current request is not a multipart request 问题处理(postman添加MultipartFile)
576 0
|
Java 应用服务中间件 Linux
SpringBoot - Processing of multipart/form-data request failed. Unexpected EOF read on the socket
SpringBoot - Processing of multipart/form-data request failed. Unexpected EOF read on the socket
1514 0
SpringBoot - Processing of multipart/form-data request failed. Unexpected EOF read on the socket
|
Java
解决An exception occurred processing JSP page
解决An exception occurred processing JSP page
246 0
|
存储 缓存 Java
【Java异常】org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet requ
【Java异常】org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet requ
454 0
|
人工智能 Java 应用服务中间件
SpringBoot实战(十一):MultipartException: Could not parse multipart servlet request
SpringBoot实战(十一):MultipartException: Could not parse multipart servlet request
274 0