- 浏览: 502121 次
- 性别:
- 来自: 沈阳
文章分类
- 全部博客 (437)
- Windows设置 (2)
- oracle数据库 (39)
- bug--jsp (4)
- j2se (13)
- js (40)
- bug-tomcat不能启动程序 (1)
- Hibernate (29)
- eclipse (20)
- java (65)
- 设计模式 (6)
- bug (18)
- PL/SQL (11)
- 前台 (5)
- 杂谈 (25)
- UML (1)
- jdbc编程 (2)
- 技术调研 (1)
- 数据通信 (2)
- ios (1)
- servlet自学笔记 (10)
- tomcat (9)
- SQL学习笔记 (6)
- java工具 (1)
- 数据库设计 (4)
- javascript (10)
- jsp (11)
- struts (17)
- ajax (7)
- linix/Unix (6)
- 资源 (3)
- spring (14)
- 算法 (5)
- 计算机网络 (2)
- http (5)
- c++ (2)
- web应用 (3)
- jvm (5)
- java中的字符编码 (14)
- java代码库 (2)
- classloader (1)
- 读书笔记 (1)
- c (1)
- 开源软件 (1)
- svn (1)
- AOP (1)
- java序列化 (1)
- 多线程 (4)
- The legendary programmers (1)
- Apache http Server (1)
- html tag (3)
- struts1.X学习笔记 (5)
- buffalo (1)
- 自己收藏 (0)
- TOEFL(IBT) (1)
- 网络翻墙 (0)
- 编译原理 (1)
- 书籍推荐 (1)
- css (10)
- javaee环境搭建资料 (1)
- 开源工具 (1)
- 美国生活 (1)
- spring自学 (3)
- log4j (3)
- 算法与数据结构 (5)
- 病毒,插件处理大全 (1)
- flex (2)
- webservice (1)
- git (7)
- cs (1)
- html (4)
- javaee (6)
- 开车 (0)
- springmvc (3)
- 互联网架构 (2)
- intellij idea (18)
- maven (15)
- mongodb (2)
- nginx (1)
- react (3)
- java基础例子 (2)
- springboot (2)
- 培训 (5)
- mysql (3)
- 数据库 (3)
- 生活 (2)
- intellij (3)
- linux (2)
- os (3)
最新评论
-
潇洒天涯:
[color=blue][color=cyan] ...
oracle 通过 nvl( )函数sql 查询时为 空值 赋默认值 -
hekai1990:
受教了..
oracle中的varchar2
前一段时间刚来公司,看到一个项目中以前有人写的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。 看这几行: 这几行的意思很明白,如果没有在配置文件中配置MultipartRequestHandler实现类的绝对路径,那就使用org.apache.struts.upload.CommonsMultipartRequestHandler类默认处理。 ^_^,这就是关键了:struts是默认使用org.apache.struts.upload.CommonsMultipartRequestHandler类来处理FormFile指定的上传文件的。 马上转到org.apache.struts.upload.CommonsMultipartRequestHandler来看看: 还有,最最重要的实现方法: /** 再看看这个函数内部是怎么实现的吧? 接着看handleRequest如何处理request的: 这次一目了然了: 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函数: 好了,替代类写好了,我们怎么去用呢? 这样:在struts-config文件中写配置: 好了!现在我们再用FormFile上传文件,一旦上传过程中出现了异常,就会被写入request的attributs里。当进入action的时候,通过在Action里获取异常就可以判断上传过程中出了什么问题了,而且在上传过程中文件一旦超出了规定大小,或者磁盘大小不足的情况会立即中断上传的。这样我们的功能就实现了。 最后,感慨一下,
/**
* 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;
}
/**
*默认文件上传的大小是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));
// 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);
}
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)
{
// 请求文件的size超出了规定的大小.
request.getSession().setAttribute(BasicConstants.baseFileSizeLimitExceededException, e);
return;
}
catch (FileUploadBase.IOFileUploadException e)
{
// 文件传输出现错误,例如磁盘空间不足等.
request.getSession().setAttribute(BasicConstants.baseIOFileUploadException, e);
return;
}
catch (FileUploadBase.InvalidContentTypeException e)
{
// 无效的请求类型,即请求类型enctype != "multipart/form-data"
request.getSession().setAttribute(BasicConstants.baseInvalidContentTypeException, e);
return;
}
catch (FileUploadException e)
{
// 如果都不是以上子异常,则抛出此总的异常,出现此异常原因无法说明.
request.getSession().setAttribute(BasicConstants.FileUploadException, e);
return;
}
// Partition the items into form fields and files.
Iterator iter = items.iterator();
while (iter.hasNext())
{
FileItem item = (FileItem) iter.next();
if (item.isFormField())
{
addTextParameter(request, item);
}
else
{
addFileParameter(item);
}
}
}
其它部分均未做什么大改变。
<!-- ========== Controller Configuration ================================ -->
<controller>
<!-- The "input" parameter on "action" elements is the name of a
local or global "forward" rather than a module-relative path -->
<set-property value="true" property="inputForward" />
<set-property value="text/html; charset=UTF-8"
property="contentType" />
<!-- 通过写类的全名来替代struts默认的MultipartRequestHandler -->
<set-property property="multipartClass" value="com.amplesky.commonmodule.struts.AmpleskyMultipartRequestHandler" />
<!-- 规定的上传文件的最大值 -->
<set-property property="maxFileSize" value="15M" />
<!-- 缓冲区大小 -->
<set-property property="memFileSize" value="5M" />
</controller>
发表评论
-
struts1 一次提交多个ActionForm
2015-11-11 17:10 770JSP中有两个actionform放在同一个form中,分别 ... -
【转】Struts 1.x 配置文件详解(下)
2015-03-15 14:30 7429) form-property标记 form- ... -
【转】Struts 1.x 配置文件详解(上)
2015-03-15 14:29 746使用Struts框架的一个好处就是可以用外部配置文件声明的方 ... -
【转】web.xml文件分析
2015-03-15 14:28 637<?xml version="1.0&quo ... -
【转】创建JavaBean的几种方法
2012-12-17 14:00 1989创建一个Bean的方法有很多种,并且在完成JavaBean ... -
【转】很详细的spirng+struts+hibernate实例
2012-12-13 14:17 2378本文并不想介绍Struts,Spring,Hiber ... -
struts bean:write标签页面换行显示的问题
2012-08-22 14:09 1543目前系统中,用户在输 ... -
【转】struts教程
2012-08-15 14:56 1438概述 本文主要讲解什么是Struts Fra ... -
【转】struts文件上传,各种类型对应的MIME配置类型大全
2012-08-09 16:04 1219.a' : 'application/octet-s ... -
【转】struts ActionForm数据类型不匹配
2012-08-09 16:03 1031报错信息: java.servlet ... -
【转】struts1 中ActionForm赋值原理
2012-07-18 17:36 927在struts1中,当点击submit页面提交后, 由 A ... -
【转】Struts2教程7:上传任意多个文件
2012-07-17 17:39 885从《Struts1.x系列教程(8):上传单个文件》中给出的例 ... -
Cannot find bean XXXForm in any scope
2012-06-15 13:43 1016action-mappings > < ... -
【转】JSP 防止重复提交 防止重复刷新 防止后退问题以及处理方式
2012-06-07 11:18 979一。前言你在任何一个比较专业的BBS都会看到这样的问题 ... -
javax.servlet.jsp.JspException: Define tag cannot set a null value”。
2012-04-24 17:06 1219原因是他调用了bean:define标签,却又再次执行了一个a ... -
StrutsBug
2012-04-13 17:52 1039type Exception report messag ...
相关推荐
`commons-fileupload-1.2`很可能是这个组件的一个版本,它提供了API来方便地处理文件上传请求。 在描述中提到的"Upload.java",这可能是实现文件上传功能的一个Java源代码文件。在这个文件中,开发者可能会使用 ...
Java文件上传组件 COS FAT文件系统读写类库 fat32-lib fat32-lib 是一个用来读写 FAT 16/32 格式文件系统的纯 Java 类库(纯的)。 Eclipse的HTML格式化插件 Eclipse Tidy Eclipse HTML Tidy 是一款 Eclipse 的...
Java文件上传组件 COS FAT文件系统读写类库 fat32-lib fat32-lib 是一个用来读写 FAT 16/32 格式文件系统的纯 Java 类库(纯的)。 Eclipse的HTML格式化插件 Eclipse Tidy Eclipse HTML Tidy 是一款 Eclipse 的...
Java文件上传组件 COS FAT文件系统读写类库 fat32-lib fat32-lib 是一个用来读写 FAT 16/32 格式文件系统的纯 Java 类库(纯的)。 Eclipse的HTML格式化插件 Eclipse Tidy Eclipse HTML Tidy 是一款 Eclipse 的...
Java文件上传组件 COS FAT文件系统读写类库 fat32-lib fat32-lib 是一个用来读写 FAT 16/32 格式文件系统的纯 Java 类库(纯的)。 Eclipse的HTML格式化插件 Eclipse Tidy Eclipse HTML Tidy 是一款 Eclipse 的...
Java文件上传组件 COS FAT文件系统读写类库 fat32-lib fat32-lib 是一个用来读写 FAT 16/32 格式文件系统的纯 Java 类库(纯的)。 Eclipse的HTML格式化插件 Eclipse Tidy Eclipse HTML Tidy 是一款 Eclipse 的...
Java文件上传组件 COS FAT文件系统读写类库 fat32-lib fat32-lib 是一个用来读写 FAT 16/32 格式文件系统的纯 Java 类库(纯的)。 Eclipse的HTML格式化插件 Eclipse Tidy Eclipse HTML Tidy 是一款 Eclipse 的...
Java文件上传组件 COS FAT文件系统读写类库 fat32-lib fat32-lib 是一个用来读写 FAT 16/32 格式文件系统的纯 Java 类库(纯的)。 Eclipse的HTML格式化插件 Eclipse Tidy Eclipse HTML Tidy 是一款 Eclipse 的...
Java文件上传组件 COS FAT文件系统读写类库 fat32-lib fat32-lib 是一个用来读写 FAT 16/32 格式文件系统的纯 Java 类库(纯的)。 Eclipse的HTML格式化插件 Eclipse Tidy Eclipse HTML Tidy 是一款 Eclipse 的...
Java文件上传组件 COS FAT文件系统读写类库 fat32-lib fat32-lib 是一个用来读写 FAT 16/32 格式文件系统的纯 Java 类库(纯的)。 Eclipse的HTML格式化插件 Eclipse Tidy Eclipse HTML Tidy 是一款 Eclipse 的...
Java文件上传组件 COS FAT文件系统读写类库 fat32-lib fat32-lib 是一个用来读写 FAT 16/32 格式文件系统的纯 Java 类库(纯的)。 Eclipse的HTML格式化插件 Eclipse Tidy Eclipse HTML Tidy 是一款 Eclipse 的...
Java文件上传组件 COS FAT文件系统读写类库 fat32-lib fat32-lib 是一个用来读写 FAT 16/32 格式文件系统的纯 Java 类库(纯的)。 Eclipse的HTML格式化插件 Eclipse Tidy Eclipse HTML Tidy 是一款 Eclipse 的...
Java文件上传组件 COS FAT文件系统读写类库 fat32-lib fat32-lib 是一个用来读写 FAT 16/32 格式文件系统的纯 Java 类库(纯的)。 Eclipse的HTML格式化插件 Eclipse Tidy Eclipse HTML Tidy 是一款 Eclipse 的...
Java文件上传组件 COS FAT文件系统读写类库 fat32-lib fat32-lib 是一个用来读写 FAT 16/32 格式文件系统的纯 Java 类库(纯的)。 Eclipse的HTML格式化插件 Eclipse Tidy Eclipse HTML Tidy 是一款 Eclipse 的...
而越来越多专业知识的 Blog 的出现,让我们看到了 Blog 更多所蕴涵的巨大的信息价值:不同的 Blog 选择不同的内容,收集和整理成为很多人关注的专业 Blog ——目前越来越多的人获取信息的来源是一些固定的 Blog 。...