Struts2 File Upload and Download.docx
《Struts2 File Upload and Download.docx》由会员分享,可在线阅读,更多相关《Struts2 File Upload and Download.docx(12页珍藏版)》请在冰豆网上搜索。
![Struts2 File Upload and Download.docx](https://file1.bdocx.com/fileroot1/2023-1/2/ea5c4f8a-b359-418c-9ec8-f67f4367588a/ea5c4f8a-b359-418c-9ec8-f67f4367588a1.gif)
Struts2FileUploadandDownload
Struts2FileUploadandDownload
上一篇/下一篇 2010-04-1522:
42:
06/个人分类:
JEE
查看(693)/评论(0)/评分(0/0)
记得自己当年自学JSP的时候看到文件上传和下载的时候自己很激动,因为基本上任何系统里面都或有这个功
能模块,所以当时就看的很仔细,当初还使用的是SmartUpload,当自己后来慢慢的接触后,逐步对文件的上传和下
载有了重新的认识和体会,目前主要使用的MVC开源架构是Struts,所以这里笔者就以Struts2为例,讲解下关于
Struts2的文件上传和下载的机制。
如果大家要使用struts2的文件上传功能那么需要导入commons-fileupload.jar和commons-io.jar文件,如
果你使用的是Struts2的最小依赖包,这里可以不用再额外导入!
我们首先看下struts2默认支持的有那些开源的第三方的文件上传和下载,在struts的核心包中的
default.properties中我们可以看到如下片段:
#struts.multipart.parser=cos
_y_tY_d_P7{0 #struts.multipart.parser=pell
_c)^H7x:
]{_@/{;D0 struts.multipart.parser=jakarta中文JAVA技术网-Z_`_n/S+@_km(@_f_?
#usesjavax.servlet.context.tempdirbydefault中文JAVA技术网!
~&X#{;M_H_X_M+v1W7v_q$c
struts.multipart.saveDir=
G3k:
QwsJ0 struts.multipart.maxSize=2097152
#在properties中代表注释,其中cos是著名的Oreilly组织开发的,这里大家可以获取以下几点信息:
1、properties中的注释怎么写?
2、struts2默认都支持哪几种文件上传和下载
3、上传文件的临时目录默认是没有的
4、struts2的默认上传和下载使用的是jakarta下的commons-fileupload组件,最大允许一次上传的文件大小为
2M多一点(配置中以字节为单位)!
当然了大家如果要使用其他的上传组件,可以将相关的语句注释删除,给默认的添加#,并导入相关的jar就可
以了,这就是struts2的灵活性!
在讲具体的文件上传的时候大家要考虑一个问题:
当一个参数是文件时,传统的表单字段是否可行?
传统表单字
段值的获取方式是否可行?
很明显传统的获取表单的一套方法这里已经不可使用了,因为文件是二进制字节流,所以这里先给大家讲解下
基于web的几种字段编码方式:
1、application/x-www-form-urlencoded我们一般的默认的使用的编码方式URL编码
2、multipart/form-data主要用于以二进制流的方式传输表单字段的数据
3、text/plain主要用于直接通过表单发送邮件如:
mailto:
所以这里大家在做文件的时候一定要清楚一点你的表单的编码方式一定要采用第2种,否则就会出现问题!
Struts2上传页面upload.jsp
form.action="uploadaction"method="post"enctype="multipart/form-data">
9{.B-hE0|0 textfieldname="info"label="描述">
textfield>
_S_v0x,r,G7`0 filename="upload"label="文件一">
file> 中文JAVA技术网_Q8s_\_c_P
filename="upload"label="文件二">
file>中文JAVA技术网_QK/O3W_^
submitvalue="上传">
submit>中文JAVA技术网_b_X_X_b_w7j$Ia
form>
这里笔者故意设置了一个一般字段和多个文件字段
(2),因为笔者在刚开始使用SmartUpload的时候就遇到这样的
问题,如果上传的文件字段和一般的普通表单字段放在一起的时候不能获取一般的表单字段,当初刚使用
SmartUpload的时候没有看它的API,后面有时间看的时候才发现要使用组件自带的request对象,随意这里大家就要
注意struts2的文件上传了。
第二点是直接看下struts2对文件的批量上传的处理,有些人就不明白了?
为什么要直接讲
多文件上传呢?
呵呵,因为在struts2中单个文件上传和多文件的上传是一致的,只要会一个,另一个就显的很简单
了!
处理的文件上传的action:
UploadAction.java
publicclassUploadActionextendsActionSupport{中文JAVA技术网_m2?
@___X_F9m)@
privateListupload;中文JAVA技术网n_E_@!
YJ%~_Hk1M9CV4a_p_F
privateStringpath;中文JAVA技术网_y_e_R_]p,m_@7[
privateStringinfo;中文JAVA技术网-M/T_g_EEu_a[&a
privateListuploadContentType;中文JAVA技术网5R@1?
_J&o$L1V
privateListuploadFileName; //当然这里可以使用数组
get、set();
publicStringgetPath(){中文JAVA技术网_z_b_S!
m_K&r_g
returnServletActionContext.getRequest().getRealPath(path); // 获取存放路径的绝对路径中文JAVA技术网"s/u_Vu_Cl
G
}
publicvoidupload(inti)throwsException{中文JAVA技术网0Z_`,w_n+b_gQ_Be
InputStreamfio=newFileInputStream(upload.get(i));中文JAVA技术网9x0E_w$m3t:
D;\7d_M
OutputStreamfou=newFileOutputStream(getPath()+"\\"+uploadFileName.get(i));中文JAVA技术网;mk+oA;{
System.out.println(getPath()+"\\"+upload.get(i).getName());
:
n,D_]$T+B']-^_x0 byte[]buf=newbyte[1024];
m/b_Ns/U)b_D_?
_|0 intlength=0;中文JAVA技术网_|
p_T_r_|!
O
while((length=fio.read(buf))>0){
(l_c.J8W1`_?
"j0 fou.write(buf,0,length);
4@/[(B:
J_y_^0 }
T|)ED_b_A0 }
注意上面在拼接输出文件的绝对路径的时候,文件名不要用upload.get(i).getName()!
通过遍历用户的上传文件数目一个一个上传。
publicStringexecute()throwsException{中文JAVA技术网_S_Z(H_C_h_T+s
for(inti=0;i upload(i);
0K+]-y5@_S_p_O0j%t0 }
_odg_xu})h0 returnSUCCESS;
_u*Y&W_aS:
B8Y0 }
这里笔者要解释的是关于XXXFileName和XXXContentType属性,至于upload属性和表单字段的对应,而且struts
帮我们将用户上传的每个字段都分装为一个File对象,便于开发人员操作!
注意的是在多文件上传时要注意每个
textfield的name要相同,且与action的字段想匹配!
struts为了方便开发人员会默认的将用户上传的文件的名字和类型
分装在XXXFileName和XXXContentType中!
细心的人们会发现action中的path是没有值的,所以这里就带大家去看下struts.xml文件:
中文JAVA技术网1d_L0L_z_n:
ff,M
/upload
&])x"^__1Z8O,x_O0 /success.jsp中文JAVA技术网_jw_T_H/j%D(R1}_`
/index.jsp
在配置文件中通过DI来注入值,这样可以增强程序的灵活性!
这里要提醒大家的是最好为action提供input视图,
因为在很多情况下struts会默认找input视图,比如:
校验、上传等!
此时你会看到你的上传文件后在服务器的日志中打印没有临时目录的消息,所以这里要设置
\\jiao">常量,或者在struts.propertes或者
在web.xml中!
仔细的人会发现临时目录是有struts维护的。
如何使用限制上传文件的大小和类型呢?
最佳的答案文件上传拦截器(FileUploadInterceptor)
查看该拦截器的源代码片段如下:
protectedLongmaximumSize; //文件的最大值
y_v_\_z0fz_E;s0 protectedSetallowedTypesSet=Collections.emptySet(); //接受文件的类型
所以这里可以给上传的action提供参数,来DI相关的参数!
具体如下配置:
中文JAVA技术网,rj_wS8?
4p
image/jpg,image/JPEG中文JAVA技术网_R6\3?
3q'a5f:
l
2000中文JAVA技术网_N_h_A#J2w_|,L3O_\
*[5?
_O_A%w*m_v*c;W_`0
这里我说过一旦我们的action显式的配置了拦截器,那么strtus的拦截器就无效了,所以我们还有手工添加struts的默认拦截器栈,聪明的你估计会问默认的拦截器栈里面不是有这个拦截器吗?
我们为什么还要自己配置呢?
呵呵!
问的好,这里配置是为了个拦截器加参数,如果开发人员配置的拦截器是struts默认拦截器有的,这里struts框架自己会判断该拦截器是否已经执行了,如果执行了,相同的拦截器就不会再次执行!
这里还要说明2点:
1、allowedTypes这个参数接受的是文件的MIME类型,不清楚的人可查看相关文档,这里笔者就不列举了!
2、maximumSize单位是字节
此时的文件上传已经好了,但是当你上传的文件过大、或者没有在允许的范围内的话,会出现一些显眼的英文,这就又涉及到了struts2的国际化了,查看struts-messages.properties文件,根据错误消息找到对应的消息的key值,开发人员自己建立资源文件加载其中的中文字段就OK啦!
通过上述大家已经可以掌握struts2的文件上传了,接下来我们讲解下下载:
其实如果说文件上传是文件的复制(输入--》输出)的话,那么文件的下载就是文件的输出,所以当用户下载文件的
时候从技术角度看,就是一个文件的输出流在通过缓存输出文件!
难道不是吗?
呵呵
但是这里大家要注意的是strus2帮我们提供好了输出流,所以在下载的时候我们要给输出流提供一个输入流!
既然是一个输入流那么就要考虑2个问题:
1、文件位置+文件名
2、文件流的获取+返回
下载文件的action:
DownloadAction.java
publicInputStreamgetDownloadFile(){ 中文JAVA技术网_l_a_g_l_x#S*L9W
return ServletActionContext.getServletContext().getResourceAsStream(path+fileName); 中文JAVA技术网:
O&W'U_j_K-}_j/?
.b
}
//path和fileName可以写死在程序中(硬编码)、或者注入进来(配置action时采用param)、请求参数传递过来
中文JAVA技术网_j*Z_z_`Z_i_JW!
K-[
W_C_s4q)R_o0
--下载文件类型定义--> 中文JAVA技术网_i_S9G6N_R;y5`
text/plain 中文JAVA技术网_v_T&]_d_z.s_|_A0r.Q
--下载文件处理方法--> 中文JAVA技术网_m#Y_`_z5g_f
中文JAVA技术网/F_s"k+R_o"N_m_n.h+SJ@_x_m
attachment;filename="jiao.txt"
|_H0q_L9n8b_I%m0
+C/G[_C.jf.`q_Z0
--下载文件输出流定义--> 中文JAVA技术网.l'c_O&]8|_o;U7W
downloadFile中文JAVA技术网4`_Z'[4I_BK\2`
中文JAVA技术网_q)mw_x_L:
__K:
g_\
contentType:
下载文件的内容类型!
contentDisposition:
通知浏览器对于该文件的处理方式,默认是inline的,也就是在页面试图打开文件,这里采用附件的形式,通知浏览器给客户端提供一个保存窗口来另存为文件!
inputName:
告诉strutsaction中的哪个方法给输出流提供输入流。
这里的三个参数没有必要记忆,大家可以参考stream对应的Result查看源代码:
protectedStringcontentType="text/plain";
_x"D_D_M.E-S_B_z0 protectedStringcontentLength;中文JAVA技术网~%U_L_e)A_y"i_K
protectedStringcontentDisposition="inline";
:
U(a_d\_K_@_?
_v9Z_Fk0 protectedStringcontentCharSet;
HH'q_a.^6b.p_]"Y0 protectedStringinputName="inputStream";中文JAVA技术网_V5A_xE&UDh
protectedInputStreaminputStream;
+{~^_G_Z_?
l0 protectedintbufferSize=1024;中文JAVA技术网5{(M{)m-E_v_h_X:
j_u
protectedbooleanallowCaching=true;
此时大家就可以看到这些参数的默认值都是什么了!
呵呵,这就是学习开源技术的一种手法,现在市场上的SSH书那么贵,对于学习者而言官方文档是最好的选择、也是最佳的选择!
不知道很多人都会遇到乱码问题,这里笔者告诉大家一个屡试不爽的方法:
1、和struts2保持统一的编码方式(默认是UTF-8)
2、获取用户的文件名后newString(name.getBytes("ISO-8859-1"),UTF-8);
到此struts2的文件上传和下载就讲完了,呵呵,写这个只是为了方便大家学习,有错误之处请不吝赐教,也希望大家提宝贵意见,如果是高手请路过!
呵呵......闲暇之余随笔........
教学反馈:
学完了文件的上传和下载,struts2的基本知识和核心的知识基本就告一段落了,呵呵,今天学生在实验的时候遇到一个问题,问题描述:
文件上传可以,而且上传的目录中可以正常显示中文的文件,但是在下载中文文件的时候遇到一个无效参数的问题:
java.lang.IllegalArgumentException:
Cannotfindajava.io.InputStreamwiththename[downloadFile]intheinvocationstack.Checkthetagspecifiedforthisaction.
此时可以从错误中分析是由于下载时候的编码和中文冲突的问题!
这里要采用的是告诉浏览器在URL编码的时候如何编码,记得一般我们在配置Tomcat的时候都是会去配置两个文件:
Tomcat的安装目录下的conf:
server.xml和context.xml文件要添加如下的信息:
server.xml:
#K_}!
J^u_Pf_m0 connectionTimeout="20000"中文JAVA技术网_O9_3k_oh8F_M_T)^
redirectPort="8443"中文JAVA技术网&|^"M!
SG
URIEncoding="UTF-8" //注意这里中文JAVA技术网_H9D_f_M_?
e&Z6|_i_?
7n_g
/>
URIEncoding="UTF-8"
;r+?
}_a_d_r_J0 />
这样使用URL编码是就会采用UTF-8的编码方式了!
当然了,对于实验的时候大家可能都采用的是Myeclipse自带的tomcat所以这里大家要去寻找自带的tomcat所在的路径,找到conf的配置文件,然后如上配置就OK啦,呵呵,感谢这位学生提出的问题!
教学反馈2:
在学生的上机实验中有同学想把上传的文件放在项目的根目录下,这个时候问我路径要怎么写?
解决方案:
上传的时候提供"/"路径为保存路径,同时在下载的时候也要设置相同的路径!
这里推荐大家还是要把上传的文件统一按类放在不同的文件目录中,1、便于管理 2、便于下载。
还有就是有些人采用的是IE8的话文件在上传的时候
默认会改变路径,所以大家要去在IE的选项中设置安全级别,详细见邮件开发的文章!
还有就是大家对于上传文件目录的建立可以直接在Web-Root目录下创建一个文件目