日期:2014-05-17  浏览次数:20710 次

上传图片失败
做网页的时候写的上传图片的功能,在公司的网络上传图片就很正常,在家里就怎么都上传不上去,有人遇到过这种网络不一样导致上传功能不好用的情况吗? 

------解决方案--------------------
错误是 还没上传完就断开连接了。是不是你窗口关闭了
------解决方案--------------------
引用:
做网页的时候写的上传图片的功能,在公司的网络上传图片就很正常,在家里就怎么都上传不上去,有人遇到过这种网络不一样导致上传功能不好用的情况吗? 

问题分析:

在我使用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以后的版本才有的类。