- 浏览: 109318 次
- 性别:
- 来自: 北京
最新评论
-
nwpu7:
解决问题,感谢感谢
org.hibernate.hql.ast.HqlToken 错误weblogic异常 -
zhangna307:
如果已经有对应的hibernte-cfg.xml文件,还是报这 ...
Could not instantiate cache implementation异常处理 -
zzw118:
不错,解决了我的问题!
Could not instantiate cache implementation异常处理 -
flank.tai:
女孩的技术都这么牛!!顶。不过图片看不了呀!!!
深度技术 USB启动维护盘制作工具 -
supercode:
dell的服务器与自己diy的相同配置,价格高出多少左右
Dell PowerEdge 2800 服务器 Windows 2003安装手册
前一段时间刚来公司,看到一个项目中以前有人写的struts代码。是使用了FormFile来处理关于文件上传的模块。但是用力一段时间后,发现出问题了。写完的这个模块,上传文件是没有问题的,但是当服务器的空间较小的时候,穿一个比较大的文件就出问题了,文件还没有上传完,就抛出一个错误的页面,报告上传模块出了问题,而且是Tomcat默认的出错页面。
于是想办法,修改,查看源代码,发现原来写这段代码的人是默认等文件上传完以后进入Action了才判断文件大小是否超出了限制。
但是,默认配置下使用struts的FormFile比较特殊,FormFile是struts包对外的一个接口,而且org.apache.struts.upload包是使用的commons-fileupload-1.0进行的封装。如果使用了它来实现文件上传的功能,则必须是FormFile对象在被初始化以后才能使用,那什么时候它才是被初始化的呢?
答案是:在进入Action之前就已经初始化好了!
因此,原先的设计:在Action中判断文件大小是根本不能在上传过程中起到提示作用的,因为这时候文件已经上传完了。而且这个设计还有一个确定就是不能捕获上传过程中出现的任何问题。也就是说:在Action里我们得到的FormFile对象是上传的一个结果,而不是一个未上传好就可以使用的对象!
那如何控制FormFile上传的过程呢?显然,在Action里处理已经不能奏效了,想想别的办法,让我们翻看一下Struts的源代码找找灵感吧。
这是struts1.1的org.apache.struts.upload包的描述:
从上图我们可以看出有有CommonsMultipartRequestHandler和DiskMultipartRequestHandler两个类实现了MultipartRequestHandler接口。
大家都知道,Commons-fileupload控件在上传的时候,使用的enctype为:enctype="multipart/form-data",因此不难看出MultipartRequestHandler的实现就是来处理enctype="multipart/form-data"这样的post请求的。
但是这里有两个类,CommonsMultipartRequestHandler和DiskMultipartRequestHandler。到底哪个是处理FormFile的上传的呢?这个问题应该从org.apache.struts.config包里来找。
org.apache.struts.config包是用来处理struts配置文件的数据的包。找到org.apache.struts.config. ControllerConfig。
看这几行:
/**
* The fully qualified Java class name of the MultipartRequestHandler
* class to be used.
*/
protected String multipartClass =
"org.apache.struts.upload.CommonsMultipartRequestHandler";
public String getMultipartClass() {
return (this.multipartClass);
}
public void setMultipartClass(String multipartClass) {
if (configured) {
throw new IllegalStateException("Configuration is frozen");
}
this.multipartClass = multipartClass;
}
这几行的意思很明白,如果没有在配置文件中配置MultipartRequestHandler实现类的绝对路径,那就使用org.apache.struts.upload.CommonsMultipartRequestHandler类默认处理。
^_^,这就是关键了:struts是默认使用org.apache.struts.upload.CommonsMultipartRequestHandler类来处理FormFile指定的上传文件的。
马上转到org.apache.struts.upload.CommonsMultipartRequestHandler来看看:
/**
*默认文件上传的大小是250M
*/
public static final long DEFAULT_SIZE_MAX = 250 * 1024 * 1024;
/**
*上传文件在内存中使用的缓冲区大小,超过次数值的数据写入硬盘。
*/
public static final int DEFAULT_SIZE_THRESHOLD = 256 * 1024;
还有,最最重要的实现方法:
/**
* Parses the input stream and partitions the parsed items into a set of
* form fields and a set of file items. In the process, the parsed items
* are translated from Commons FileUpload <code>FileItem</code> instances
* to Struts <code>FormFile</code> instances.
*
* @param request The multipart request to be processed.
*
* @throws ServletException if an unrecoverable error occurs.
就是这个函数处理上传文件的request,把request交给
Commons FileUpload 控件处理,并解析FileItem转换成Struts的FormFile。
*/
public void handleRequest(HttpServletRequest request)
throws ServletException
再看看这个函数内部是怎么实现的吧?
// 使用了DiskFileUpload。
// (Commons-FileUpload很老版本的一个上传实现类了,还在用?我的显示是Deprecated)
DiskFileUpload upload = new DiskFileUpload();
// 上传最大值
upload.setSizeMax((int) getSizeMax(ac));
// 上传文件在内存中使用的缓冲区大小
upload.setSizeThreshold((int) getSizeThreshold(ac));
// 存在硬盘的什么地方,一般是默认
upload.setRepositoryPath(getRepositoryPath(ac));
接着看handleRequest如何处理request的:
// Parse the request into file items.
List items = null;
try {
items = upload.parseRequest(request);
} //这里是关键:上传过程中出了超出最大值的异常了,如何处理?
catch (DiskFileUpload.SizeLimitExceededException e) {
// Special handling for uploads that are too big.
request.setAttribute(
MultipartRequestHandler.ATTRIBUTE_MAX_LENGTH_EXCEEDED,
Boolean.TRUE);
return;
}
//出了其他异常,如enctype不对,磁盘空间不足怎么办?
catch (FileUploadException e) {
log.error("Failed to parse multipart request", e);
throw new ServletException(e);
}
这次一目了然了:
Struts根本没有把上传过程中出的超出最大值的异常带到Action,因为那是不可能的,而是把它放到了rquest的Attribute里。
而出了其他异常如enctype不对,磁盘空间不足怎么办?很遗憾,Struts没有去处理它,而是log了一下,抛给了上一层了。
那我一定要获得这些全部异常咋办呢?没办法,自己定制一个MultipartRequestHandler吧,那样就能彻底解决上传过程中的控制问题了!
在此之前,我们得先去最新版的commons-fileupload控件看看上传过程中可能抛出多少异常?
//所有上传异常的父类
org.apache.commons.fileupload.FileUploadException
//注意:这个类的类名是FileUploadBase.SizeLimitExceededException是个public内//部类。上传的formdata总的数据超出了规定大小
org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException
//注意:也是个内部类。这个才是上传的文件超出了规定大小
org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException
其它的,也看看吧:
org.apache.commons.fileupload.FileUploadBase.FileUploadIOException
org.apache.commons.fileupload.FileUploadBase.InvalidContentTypeException
org.apache.commons.fileupload.FileUploadBase.IOFileUploadException
org.apache.commons.fileupload.FileUploadBase.UnknownSizeException
要想获得尽可能仔细的数据就在处理的try/catch块里把上面的异常都catch一下,放到request的attribute里去就OK了。
另外还有要说的是,最好用commons-fileupload控件的最新版本,因为DiskFileUpload这个类,commons-fileupload已经弃用了,取而代之的是ServletFileUpload类了,所以一定要注意!切记,切记…..
这是我写的CommonsMultipartRequestHandler替代类的public void handleRequest(HttpServletRequest request) throws ServletException函数:
public void handleRequest(HttpServletRequest request) throws ServletException
...{
// Get the app config for the current request.
ModuleConfig ac = (ModuleConfig) request.getAttribute(Globals.MODULE_KEY);
// DiskFileItem工厂,主要用来设定上传文件的参数
DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
// 上传文件所用到的缓冲区大小,超过此缓冲区的部分将被写入到磁盘
fileItemFactory.setSizeThreshold((int) this.getSizeThreshold(ac));
// 上传文件用到的临时文件存放位置
fileItemFactory.setRepository(this.getRepository(ac));
// 使用fileItemFactory为参数实例化一个ServletFileUpload对象
// 注意:该对象为commons-fileupload-1.2新增的类.
// 对于1.2以下的commons-fileupload版本并不存在此类.
ServletFileUpload upload = new ServletFileUpload(fileItemFactory);
// 从session中读取对本次上传文件的最大值的限制
String maxUploadSize = (String) request.getSession().getAttribute(BasicConstants.maxUploadSize);
// 获取struts-config文件中controller标签的maxFileSize属性来确定默认上传的限制
// 如果struts-config文件中controller标签的maxFileSize属性没设置则使用默认的上传限制250M.
long defaultOrConfigedMaxUploadSize = this.getSizeMax(ac);
if (maxUploadSize != null && maxUploadSize != "")
...{
// 如果maxUploadSize设定不正确则上传限制为defaultOrConfigedMaxUploadSize的值
// 正确则为maxUploadSize转换成的字节数
upload.setSizeMax((long) this.convertSizeToBytes(maxUploadSize, defaultOrConfigedMaxUploadSize));
}
else
...{
// 如果maxUploadSize没设置则使用默认的上传限制
upload.setSizeMax(defaultOrConfigedMaxUploadSize);
}
// 从session中清空maxUploadSize
request.getSession().removeAttribute("maxUploadSize");
// Create the hash tables to be populated.
elementsText = new Hashtable();
elementsFile = new Hashtable();
elementsAll = new Hashtable();
// Parse the request into file items.
List items = null;
// ServletFileUpload类来处理表单请求
// 抛出的异常为FileUploadException的子异常
// 如果捕获这些异常就将捕获的异常放到session中返回.
try
...{
items = upload.parseRequest(request);
}
catch (FileUploadBase.SizeLimitExceededException e)
...{
// 请求数据的size超出了规定的大小.
request.getSession().setAttribute(BasicConstants.baseSizeLimitExceededException, e);
return;
}
catch (FileUploadBase.FileSizeLimitExceededException e)
...<
发表评论
-
求100以内的质数
2011-01-11 12:42 956题目:除了能被自身和1整除外,不能被其他数整除的数,为素数 ... -
整理开始
2010-03-15 16:49 796将近半年没来javaeye了,自己的知识没能及时梳理。从今天开 ... -
dddd
2009-09-16 17:11 819ddddddddd -
java文件上传下载
2009-09-16 17:07 5532文件上传在web应用中非常普遍,要在jsp环境中实现文件上传功 ... -
实现Ext表单对checkBoxGroup的统一管理
2009-08-11 13:21 13801 对于类型是checkboxgroup的数据,数据库中保存数 ... -
cvsnt 配置
2009-06-03 15:51 1116CvsNT设置1.安装CvsNT,并 ... -
发生算术溢出或其它算术异常。
2009-05-26 17:16 3738今天报了一个bug,sql在DB2执行的时候报“发生算术溢出或 ... -
回车代替点按钮提交
2009-05-22 16:46 1523输入框+按钮 完成的操作和 输入框+回车 完成一样的操作 & ... -
eclipse下修改代码重启tomcat的问题
2009-05-04 17:40 2281忍受了很久的eclipse下修改代码重启tomcat的问题,今 ... -
urlrewritefilter 例子
2009-04-17 17:31 1163我在tomcat下跑通了一个例子,关于urlRewritefi ... -
正则表达式
2009-03-20 17:35 848如果你曾经用过Perl或任何其他内建正则表达式支持的语言 ... -
正则表达式大全
2009-03-20 16:35 899常用正则表达式大全! ... -
Could not instantiate cache implementation异常处理
2009-03-06 14:34 8028今天遇到了一个很奇怪的问题 我照例增加了一套新功能,但一切就 ... -
整理分页
2009-02-24 16:28 876从今天开始打算整理一下分页、上传下载、程序里调用存储 ... -
Dell PowerEdge 2800 服务器 Windows 2003安装手册
2009-02-06 15:40 2254Dell PowerEdge 2800 服务器 W ... -
新年第一天的工作
2009-02-05 11:50 758初十一来上班了,工作安排是解决河北bug,但是公司服务器dow ... -
深度技术 USB启动维护盘制作工具
2009-02-05 11:27 5939前言 大容量的移动硬盘和U盘已经越来越普及,很多朋友希望将 ... -
Tomcat:IOException while loading persisted session
2009-01-05 10:20 884错误描述:....while loading persiste ... -
display tag
2008-12-29 10:19 4322DisplayTag Tutorial by DarrenWa ... -
eclipse快捷键大全
2008-12-17 17:11 617Ctrl+1 快速修复(最经典的快捷键,就不用多说了)Ctrl ...
相关推荐
Struts的FormFile与Commons-FileUpload控件使用心得。
Struts的FormFile与Commons-FileUpload控件使用心得 详细内容可以参考http://blog.csdn.net/lowkeysk/article/details/8296289
在Struts中集成`commons-fileupload`,你需要在项目的类路径中包含这个JAR包,并且配置Struts的ActionForm或自定义的Action来处理文件上传。例如,你需要创建一个继承自`org.apache.struts.upload.FormFile`的类来...
1. **文件上传组件**: 在 Struts 中,文件上传主要依赖于 `commons-fileupload` 和 `commons-io` 这两个 Apache Commons 库。`Commons-fileupload` 提供了处理 HTTP 多部分请求的能力,而 `Commons-io` 提供了文件...
本文将深入探讨如何使用FormFile在Struts1.2中实现实现批量文件上传,以及相关的技术要点。 一、Struts1.2简介 Struts1.2是Apache软件基金会开发的一款基于MVC(Model-View-Controller)设计模式的Java Web应用框架...
在进行文件上传操作时,通常需要使用Apache Commons FileUpload组件。这是一个功能强大的文件上传组件,能够处理HTTP协议中的multipart/form-data类型的数据格式,这是大多数浏览器在表单中上传文件时使用的格式。...
- `commons-fileupload.jar`(用于文件上传) - `commons-logging.jar` - `commons-validator.jar` - `jakarta-oro.jar` - `struts.jar` 这些库可以确保Struts框架正常运行并支持文件上传功能。 #### 2. 配置...
本篇文章将详细探讨如何使用Struts的`FormFile`来实现批量上传图片的功能。 ### 1. FormFile概述 `FormFile`是Struts的`org.apache.struts.action.ActionForm`类的一个属性,它提供了对上传文件的封装,包括文件名...
myeclipse 工程 ... 有两个例子: 一个是 jspsmart + strust 1.2 另一个用的 struts 自带的 formfile 环境:winxp jdk1.4.2 tomcat5.0或weblogic8.1 发布前,最好先编译一下,毕竟JDK版本太老了
在Struts 1.x中,文件上传主要依赖于`commons-fileupload`和`commons-io`两个库。以下是一些关键知识点: 1. **表单设置**:在HTML表单中,必须包含`enctype="multipart/form-data"`属性,以便发送二进制数据。 2....
首先,在`struts.properties`文件中指定Commons FileUpload和Commons IO的类路径: ``` struts.multipart.parser=org.apache.struts.upload.MultipartRequestHandler struts.multipart.saveDir=/tmp ``` 然后,...
在Struts中,文件上传是通过内置的Commons-FileUpload组件实现的。`FormFile` 是Struts提供的一个接口,用于处理上传的文件。在HTML表单中,设置`enctype="multipart/form-data"`使得表单能够支持文件上传。例如在`...
Struts1提供了`org.apache.struts.upload.FormFile`类来处理上传的文件。你可能需要重写`execute()`方法,代码如下: ```java public ActionForward execute(ActionMapping mapping, ActionForm form, ...
在Struts中,文件上传主要依赖于`commons-fileupload`和`commons-io`这两个库。在struts-config.xml配置文件中,你需要声明一个处理文件上传的ActionForm,比如`UploadForm`,并在其中定义一个类型为`java.io.File`...
在服务器端,你需要使用Apache的Commons FileUpload库来解析上传的文件。首先,确保在项目中引入了这个库。然后,在Action的execute方法中,使用`ServletFileUpload`和`FileItemIterator`来迭代并处理每个上传的文件...
在Struts框架中,文件上传通常使用Apache Commons FileUpload库来处理。这个库提供了一套API,使得开发者能够方便地从HTTP请求中解析出上传的文件。 首先,我们需要在Struts配置文件(struts-config.xml)中配置...
每个ActionMapping对应一个ActionForm,这个Form类需要继承自Struts1的`org.apache.struts.upload.FormFile`类或者使用第三方库如Commons FileUpload。 3. **使用第三方库**:Apache Commons FileUpload是Java中...
Struts2提供了一个`FileUpload`拦截器,用于处理文件上传请求。在Action类中,我们需要定义一个或多个`java.io.File`或`org.apache.struts2.dispatcher.multipart.FileItem`类型的属性,这些属性会被用来存储上传的...
import org.apache.struts.upload.FormFile; ... public class UploadAction extends ActionSupport { private FormFile file; public String execute() { if (file != null && !file.isEmpty()) { File local...
1. **灵活性**:Struts 2的文件上传功能比Struts 1.x更强大,且与整个框架集成度高。而SmartUpload作为独立库,提供了更多自定义选项。 2. **易用性**:对于熟悉Struts的开发者来说,Struts 2的文件上传配置相对简单...