• Struts FileUpload 异常处理之Processing of multipart/formdata request failed.


    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代码 <!-- 临时文件存放路径 -->      <constant name="struts.multipart.saveDir" value="D://chain/jboss-web/MyTemp/"></constant>  

    <!-- 临时文件存放路径 --> <constant name="struts.multipart.saveDir" value="D://chain/jboss-web/MyTemp/"></constant>

     有待测试验证.

  • 相关阅读:
    elemeng-ui中el-select的默认选择项问题
    element-ui的rules中正则表达式
    时间戳格式化
    array排序(按数组中对象的属性进行排序)
    vue-router路由传参
    flex属性flex-grow、flex-shrink、flex-basis
    sessionStorage、localStorage与cookie
    并发编程学习之线程可见性
    JVM系列文章合集
    JVM(1):Java 类的加载机制
  • 原文地址:https://www.cnblogs.com/yaowukonga/p/2516715.html
Copyright © 2020-2023  润新知