《开始Struts 2》
第七章
struts2的上传下载
序
文件上传是Web应用经常需要面对的问题,在大部分时候,用户的请求参数是在表单域输入的字符串,但如果为表单元素设置enctype="multipart/form-data”属性,则提交表单时不再以字符串方式提交请求参数,而是以二进制编码的方式提交请求,此时直接通过HttpServletRequest的getParamete:方法无法正常获取请求参数的值,我们可以通过二进制流来获取请求内容—通过这种方式,就可以取得希望上传文件的内容,从而实现文件的上传。
Struts 2 未提供自己的请求解析器,也就是说,Struts 2不会自己去处理multipart/form-data的请求,它需要调用其他请求解析器,将HTTP请求中的表单域解析出来。但Struts 2在原有的上传解析器基础上做了进一步封装,更进一步简化了文件上传。
在Struts 2的struts.properties配置文件中,我们看到了下面的配置代码,它们主要用于配置Struts 2上传文件时的卜传解析器。
#指定使用cos的文件上传解析器
# struts.multipart .parser=cos
#指定使用Pell的文件上传解析器
#struts.multipart.parser=pell
#Struts 2默认使用Jakarta的Common-FileUpload的文件上传解析器
struts.multpart .parser=jakarta
Struts 2默认使用的是Jakarta的Common-FileUpload的文件上传框架,要使用Struts 2的文件上传功能,则需要在Web应用中增加两个commons-io-1.3. l .ja:和commons-fileupload-1.2. jar
文件上传
例子:
上传页面
uload.jsp
<form action="Upload.action" method="post" enctype="multipart/form-data"> 文件描述:<input type="text" name="fileDesc" /><br> <input type="file" name="file" /><br> <input type="submit" value="上传" /><br> </form> |
上传的action
private String fileDesc;//和前台的是同一个 private File file;//这是IO的File,回顾下strust1.x的FormFile //这两个字段是被注入进来的,前台页面并没有这两个表单域 private String fileFileName; private String fileContentType; /** * 获得保存的路径 */ private String getSaveDir(){ return ServletActionContext.getServletContext().getRealPath("/userDatas"); } @Override public String execute() throws Exception { System.out.println("##"+file.getName()); System.out.println("@@"+fileFileName); System.out.println("##"+fileDesc); System.out.println("##"+fileContentType); File targetFile =new File(getSaveDir()+"/"+fileFileName); file.renameTo(targetFile); return "uploadOK"; } |
配置文件:l
<package name="com.huaxia.struts2.action" extends="struts-default"> <action name="Upload" class="com.huaxia.struts2.action.Upload"> <result name="uploadOK">/uploadOK.jsp</result> </action> </package> |
值得注意的是,上面的Action还包含了两个属性:uploadFileName和uploadContentType,这两个属性分别用于封装上传文件的文件名、上传文件的文件类型。这两个属性,体现了Struts 2设计的灵巧、简化之处,Action类直接通过File类型属性直接封装了上传文件的文件内容,但这个File属性无法获取上传文件的文件名和文件类型,所以Struts 2直接将文件域中包含的上传文件名和文件类型的信息封装到fileFileName和fileContentType属性中。可以认为:如果表单中包含一个name属性为xxx的文件域,则对应Action需要使用3个属性来封装该文件域的信息:
⏹ .类型为File的xxx属性封装了该文件域对应的文件内容。这是临时文件,在action调用execute后临时文件会被删除
⏹ ·类型为String的xxxFileName属性封装了该文件域对应的文件的文件名。
⏹ ·类型为String的xxxContentType属性封装了该文件域对应的文件的文件类型。
如果要搞清楚struts的上传机制,我们可以打开strust中fileupload的源代码
上传的其他处理:
1. 限制文件的大小
2. 限制文件的上传类型
3. 上传临时目录的设定
限制文件的大小
在struts2的默认大小是2M,我们可以打开struts.properites,查看相关设置,然后在l将相关设置覆盖掉:
### Parser to handle HTTP POST requests, encoded using the MIME-type multipart/form-data
# struts.multipart.parser=cos
# struts.multipart.parser=pell
struts.multipart.parser=jakarta
# uses t.tempdir by default
struts.multipart.saveDir=
struts.multipart.maxSize=2097152
覆盖后:
<struts> <constant name="struts.multipart.saveDir" value="/upTemp" /> <constant name="struts.multipart.maxSize" value="4194304" /> <package getsavefilenamename="com.huaxia.struts2.action" extends="struts-default"> <action name="Upload" class="com.huaxia.struts2.action.Upload"> <result name="uploadOK">/uploadOK.jsp</result> </action> </package> </struts> |
这里要强调的是,我们虽然设置了文件的临时目录,而且struts2在上传动作完毕后会自动执行删除,但这个自动删除不一定每次都能删除成功的,所以struts2设定了一个filter,用来每隔一段时间检测临时目录,如果有文件则去删除,filter的配置如下
<!-- 配置Struts2的C1eanUp的Filter --> <filter> <filter-name>struts-cleanup</filter-name> <filter-class>org.apache struts2.dispatcher.ActionContextCleanUp</filter-class> </filter> <!-- 定义Struts2的C1eanUp Filter拦截的URL--> <filter-mapping> <filter-name>struts-cleanup</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> |
限制文件的类型
在查看fileupload的源代码时,我们发现如下两个属性:
1. allowedTypes
2. maximumSize
从字面猜测就是允许的上传类型和允许的上传大小,我们可以覆盖掉这两个的配置:
<package name="com.huaxia.struts2.action" extends="struts-default"> <action name="Upload" class="com.huaxia.struts2.action.Upload"> <interceptor-ref name="fileUpload" > <!-- 这里是可以上传文件的扩展名 --> <param name="allowedExtensions">jpg,gif,png</param> <!-- 这里是memi类型,在tomcat的配置文件下可以到很全的memi类型 --> <param name="allowedTypes">image/bmp,image/png,image/gif,image/jpeg,image/jpg ,image/x-png,image/pjpeg </param> <param name="maximumSize">4194304</param> </interceptor-ref> <interceptor-ref name="defaultStack" /> <result name="uploadOK">/uploadOK.jsp</result> <result name="input">/upload.jsp</result> </action> </package> |
注意如果我们设置了,就要将默认的栈也加上,在章节讲过
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论