- 浏览: 131104 次
- 性别:
文章分类
最新评论
-
seacow2008:
同1楼,深入浅出
Java并发编程(二) CountDownLatch -
Mojarra:
java0000wa 写道不能搞得通俗易懂一点? demo S ...
fastupload 0.6.0发布 -
java0000wa:
不能搞得通俗易懂一点? demo Spring jar包都少了 ...
fastupload 0.6.0发布 -
Mojarra:
tegger 写道不好意思设置字符编码解决了,还是挺好用的,不 ...
fastupload 0.6.0发布 -
tegger:
不好意思设置字符编码解决了,还是挺好用的,不错
fastupload 0.6.0发布
Struts2中,在Dispatcher.java里,把一个multipart/form-data类型的 HttpServletRequest对象包装成JakartaMultiPartRequest的过程中,已经读完了HttpServletRequest对象输入流数据,基于此对象输入流的特点--不可再读取第二次,因此Action中已经不可能使用fastupload API解析multipart/form-data请求了。
纵览struts2框架里Model Bean的自动装配过程,发现拦截器其实共享了一个ActionContext的“值栈”,“值栈”里存储了必要的数据,以便让拦截器、ActionProxy、ActionInvocation对象和HttpServletRequest隔离,最后在ParametersInterceptor.java中,从“值栈”取得相关的数据,装配到Model Bean中,因此,任何数据在装配之前,都需要在合适的时机放入“值栈”之中。Struts2虽然在包装HttpServletRequest阶段已经完成了文件解析的工作,但是直到FileUploadInterceptor被调用时,把解析的文件放入了“值栈”。
fastupload基于这个约定,编写了struts2文件上传的“插件”,之所以打上引号,其功能实质上算不了一个正真的插件,只是实现了MultiPartRequest这个接口过程中调用了fastupload相关的API。具体的用法请参考《Fastupload 0.4.7发布,支持struts2》一文。这种解决办法只能说是凑合,好处是---- 不需要修改struts2的源码。
但是struts2在使用apache commons fileupload的过程中,写的MultiPartRequestWrapper.java的构造函数是多了一个saveDir,用来指定apache commons fileupload解析时产生临时文件的存储目录,并且在ActionProxy对象执行结束后,要清除这些临时文件,不止于此,在Action中,用来操作上传的文件的类用了java.io.File,也就是一定要和文件系统相关联。不能不说,
apache commons fileupload使用临时文件这种方式,拖累了struts2,spring mvc以及其他一些mvc框架。
假如解析multipart/form-data请求后,这些解析的数据都作为内存中的一个对象存在,在需要的时候才保存到文件系统中,mvc框架处理起来要简单的多,是不是这样?正因如此,要发挥fastupload的威力,一定要用内存的解析方式!
首先看一下使用内存解析方式,Action类有何变化!
public class StrutUploadAction1 extends ActionSupport { private MultiPartFile photo; private String description; @Override public String execute() throws Exception { System.out.println(photo); //此处省略业务逻辑代码 return super.execute(); } //省略getters & setters }
这个Actin中直接使用MultPartFile,解析后的上传文件的数据也保存在这个对象之中,也就是,上传文件的数据已经在内存之中, 用户很方便的把这些数据保存到文件系统还是拿到数据,处理完后直接丢弃。这种处理方式,给予用户极大的便利。
但是,struts2对于multipart/form-data请求的解析过程中,借用了临时文件。对用户而言, 不仅 处理上传文件不方便,而且还造成WEB APP性能低下,还要在Action被代理执行后清除这些临时文件。
struts2沿用这种处理方式已久, multipart/form-data请求的处理,处处体现了这个特征。fastupload针对这种现象,作出一个小规模的源码侵入。实现的步骤如下:
1, 修改struts配置,使用FastUploadInterceptor,配置其参数,注意这个fileUploadAction配置 。
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest" name="fastupload" class="org.apache.struts2.dispatcher.multipart.FastUploadMultiPartRequest" scope="default" /> <constant name="struts.multipart.handler" value="fastupload" /> <constant name="fastupload.parse.type" value="auto"/> <constant name="fastupload.allowed.types" value="image/jpeg, image/png, image/gif"/> <constant name="fastupload.allowed.extensions" value=".jpeg, .png, .gif"/> <package name="example" namespace="/example" extends="struts-default"> <interceptors> <interceptor name="fastuploadInterceptor" class="org.apache.struts2.dispatcher.multipart.FastUploadInterceptor" /> </interceptors> <action name="fileUploadAction" class="example.FileUpload"> <interceptor-ref name="fastuploadInterceptor"/> <interceptor-ref name="basicStack"/> <result>/example/upload.jsp</result> </action> </package> </struts>
2, 修改Dispatcher.warpRequest(HttpServletRequest, ServletContext)函数,用FastUploadMultiPartRequestWrapper替换struts2原有的warpper。
//TODO un-comment the next line for original code // request = new MultiPartRequestWrapper(mpr, request, getSaveDir(servletContext)); request = new FastUploadMultiPartRequestWrapper(mpr, request, getSaveDir(servletContext));
3,既然使用了内存解析方式,不需要临时文件,也不用清理它们,注释掉Dispathcer.cleanUpRequest(HttpServletRequest)函数中所有的代码
/** * Removes all the files created by MultiPartRequestWrapper. * * @param request the HttpServletRequest object. * @see org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper * @throws java.io.IOException on any error. */ public void cleanUpRequest(HttpServletRequest request) throws IOException { // if (!(request instanceof MultiPartRequestWrapper)) { // return; // } // // MultiPartRequestWrapper multiWrapper = (MultiPartRequestWrapper) request; // // Enumeration fileParameterNames = multiWrapper.getFileParameterNames(); // while (fileParameterNames != null && fileParameterNames.hasMoreElements()) { // String inputValue = (String) fileParameterNames.nextElement(); // File[] files = multiWrapper.getFiles(inputValue); // // for (File currentFile : files) { // if (LOG.isInfoEnabled()) { // String msg = LocalizedTextUtil.findText(this.getClass(), "struts.messages.removing.file", Locale.ENGLISH, "no.message.found", new Object[]{inputValue, currentFile}); // LOG.info(msg); // } // // if ((currentFile != null) && currentFile.isFile()) { // if (!currentFile.delete()) { // if (LOG.isWarnEnabled()) { // LOG.warn("Resource Leaking: Could not remove uploaded file '" + currentFile.getCanonicalPath() + "'."); // } // } // } // } // } }
4, 使用fastupload预先的过滤机制(可选),在FastUploadMultiPartRequest类中,找到下面的代码,把@Inject那两行反注释掉,
/** * not exposed yet * * @param allowedTypes * the allowedTypes to set */ // @Inject("fastupload.allowed.types") public void setAllowedTypes(String allowedTypes) { this.allowedTypes = allowedTypes; } /** * not exposed yet * * @param allowedExtensions * the allowedExtensions to set */ // @Inject("fastupload.allowed.extensions") public void setAllowedExtensions(String allowedExtensions) { this.allowedExtensions = allowedExtensions; }
向struts配置文件中增加两个全局配置常量,这用过滤设置目前还不支持通配符,详细的用法请参考fastupload项目中的 AcceptableFileFactory.java
<constant name="fastupload.allowed.types" value="image/jpeg, image/png, image/gif"/> <constant name="fastupload.allowed.extensions" value=".jpeg, .png, .gif"/>
5, 运行并测试那个Action -:)
采用侵入源码的方式,也是逼迫不已呀。就目前来说,也达到让fastupload支持struts2的目标,但是,如果能让struts2的发行包中,直接集成了fastupload组建高效解析API,才能让struts2框架使用者更容易的使用,需要与struts的开发小组讨论了... ... 这个阶段刚 结束,一个新的阶段接着开始。
fastupload支持struts2框架的开发过程比较仓促,加之本人水平有限,可能会有一些疏漏及不正确的地方,如果您发现了,请告诉我,我及时改正,同时也欢迎网友对fastupload提出建设性意见。
[原创文章,如转载,请注明出去!@仪山湖]
发表评论
-
Fastupload 0.6.1 发布
2014-03-03 09:44 15650.6.1版本主要修复了JQuery-form提交ajax请 ... -
fastupload 0.6.0发布
2013-06-23 18:24 1780Fastupload 0.6.0完善或者新增加的功能有: ... -
uProfiler使用指南
2013-06-13 14:43 1556简介: uProfiler Community是面向主题 ... -
uProfiler Community 1.0发布
2013-06-08 09:39 1992uProfiler Community 1.0是面 ... -
fastupload-springmvc 0.5.5发布
2013-04-15 21:55 2005fastupload-springmvc是利用f ... -
Fastupload 0.5.3发布
2013-01-05 19:55 997相对于以往的版本,fastupload 0.5.3做出了明 ... -
fastupload已发布至maven中心库
2012-11-29 09:44 1029为了让大家更方便的使用fastupload开源项目,fastu ... -
白话MVC(五)初窥Spring MVC
2012-11-22 21:17 2259在 为 struts2 项 目写完 fastuplo ... -
Fastupload 0.4.7发布,支持struts2
2012-10-28 20:56 1759Fastupload 0.4.7这个版本中主要增加了支持str ... -
Fastupload 0.4.2发布
2012-10-19 12:05 1544更新:fastupload 0.4.2支 ... -
fastupload召集开源开发志愿者
2012-10-11 19:57 98fastupload开源项目自发布0.3.5版本后,文件上传的 ... -
白话MVC(三)Struts2拦截器巧妙装配Model Bean
2012-10-12 18:02 2038白话MVC(二) 在Struts的过滤器中,经过调用Prep ... -
白话MVC(二)Struts2中Model的处理基础-ActionContext
2012-10-09 13:17 2442白话MVC(一) ... -
白话MVC(一)Model的产生及处理
2012-09-29 00:36 34663白话MVC(二) 最近在带一“徒弟”,领悟能力很高,对我 ... -
fastupload API开发快速上手
2012-09-01 16:36 2897fastupload提供两种从multipart/form-d ... -
文件上传的秘密(五)0.31版本功能基本完备
2012-08-26 21:15 1400fastupload 0.31版本上周已经发布,因为工作的关系 ... -
fastupload 0.3.1发布
2012-08-21 15:25 1730fastupload根据RFC 1867文档 ... -
开源项目fastupload 0.2.3发布
2012-07-06 17:19 2004fastupload 0.2.3发布,增加了对sub-boun ... -
文件上传的秘密(四)大小限制与进度
2012-05-28 14:27 8411RFC1867规范中,对表单上传文件的大小和进度都没有作出规定 ... -
文件上传的秘密(三)性能和稳定性上的衡量
2012-05-19 22:42 2924文件上传的秘密系列之一, http://mojarra.ite ...
相关推荐
基于SpringBoot的文件上传系统,前后端分离,单文件上传,多文件上传,大文件上传,断点续传,文件秒传,图片上传 项目经过严格测试,确保可以运行! 采用前后端分离的方式进行开发,实现了几种常用的文件上传功能...
#### 四、MVC的工作流程 为了更好地理解MVC的工作流程,我们将详细探讨以下几个关键步骤: 1. **请求处理**:当用户通过浏览器发起一个HTTP请求时,请求会被发送到服务器端。服务器通过路由机制将请求映射到相应的...
Struts2作为一款强大的MVC(Model-View-Controller)框架,为Web应用提供了良好的架构支持。它简化了控制器层的编写,使得业务逻辑和视图呈现更加分离。在学生信息管理系统中,Struts2负责处理HTTP请求,调度控制...
四、文件名:与文件上传时不同。是由存储服务器根据特定信息生成,文件名包含:源存储服务器IP地址、文件创建时间戳、文件大小、随机数和文件拓展名等信息。 基于SpringBoot结合分布式文件系统FastDFS实现的文件...
### 更多Windows白话经典算法之七大排序第2版(高清) #### 一、概览 本书《更多Windows白话经典算法之七大排序第2版》是一部深入浅出讲解七种经典排序算法的著作,旨在帮助读者理解并掌握冒泡排序、直接插入排序...
基于MVC实现的门禁管理系统+毕业设计+课程设计+源码 基于MVC实现的门禁管理系统+毕业设计+课程设计+源码 基于MVC实现的门禁管理系统+毕业设计+课程设计+源码 基于MVC实现的门禁管理系统+毕业设计+课程设计+源码 ...
08 白话容器基础(四):重新认识Docker容器.pdf
python web开发,基于flask的练手项目---文件上传下载的管理系统的设计与实现 python web开发,基于flask的练手项目---文件上传下载的管理系统的设计与实现 python web开发,基于flask的练手项目---文件上传下载的...
ACM在线评测系统,可以支持C、C++和Java+Struts2 + Spring + Hibernate+课程设计+毕业设计 ACM在线评测系统,可以支持C、C++和Java+Struts2 + Spring + Hibernate+课程设计+毕业设计 ACM在线评测系统,可以支持C、...
C#+dot net+MVC+基于.net MVC的教师公寓管理系统设计与实现+本科毕业设计+课设+源码+web C#+dot net+MVC+基于.net MVC的教师公寓管理系统设计与实现+本科毕业设计+课设+源码+web C#+dot net+MVC+基于.net MVC的...
2. Struts框架接收到请求后,根据配置文件(struts-config.xml)确定要调用的Action类。 3. Action类执行相应的业务逻辑,可能涉及到对数据库的查询或更新。 4. 数据操作完成后,Action类将结果封装成一个Action...
《子平真诠白话解释》是一部对古代命理学经典著作《子平真诠》的现代解读作品,它将古典文言文译为现代白话文,旨在为现代读者提供更加通俗易懂的阅读体验。《子平真诠》由古代著名命理学者所著,对后世影响深远。...
总之,《白话C++》是一本精心编写的C++入门教材,它以其独特的“白话”风格,让编程学习不再枯燥乏味。无论你是编程新手还是寻求进阶的开发者,都能从中受益匪浅,逐步成长为熟练掌握C++的编程大师。
本资源中的源码都是经过本地编译过可运行的,下载后按照文档配置好环境就可以运行。资源项目的难度比较适中,内容都是经过助教老师审定过的,应该能够满足学习、使用需求,如果有需要的话可以放心下载使用。...
标题中的“一个基于MVC模式简单Web应用,实现远程浏览系统文件”揭示了这个项目是使用Model-View-Controller(MVC)架构设计的一个Web应用程序,它的主要功能是让用户能够远程访问并浏览服务器上的文件系统。MVC模式...
白话文运动的危机,CAJViewer 文件,使用CAJViewer软件查看
《白话C++》教程是一本面向初学者和有一定编程基础的人士的C++学习资料。本书以通俗易懂的语言,生动有趣的例子,深入浅出地解析了C++这一强大的编程语言,使得学习者能够更轻松地掌握C++的基础与进阶知识。 C++是...
### 白话C++ 关键知识点解析 #### 1. 计算机基本概念:硬件与软件 **硬件**:指的是计算机系统中的物理组件,包括中央处理器(CPU)、内存(RAM)、硬盘驱动器(HDD)、输入输出设备(如键盘、鼠标、显示器)等。...
白话投资—炒股就这么简单培训文件