第七章 struts2的上传下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《开始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
文件上传
例子:
上传页面
上传的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 {
值得注意的是,上面的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,查看相关设置,然后在struts.xml将相关设置覆盖掉:
### 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 javax.servlet.context.tempdir by default
struts.multipart.saveDir=
struts.multipart.maxSize=2097152
这里要强调的是,我们虽然设置了文件的临时目录,而且struts2在上传动作完毕后会自动执行删除,但这个自动删除不一定每次都能删除成功的,所以struts2设定了一个filter,用来每隔一段时间检测临时目录,如果有文件
限制文件的类型
在查看fileupload的拦截器源代码时,我们发现如下两个属性:
1.allowedTypes
2.maximumSize
错误信息显示:
当上传文件出现错误时,我们设定了“input”为上传页面,即出现错误的话,回到上传页面,我们在上传页面稍作修改,添加如下代码:
<s:fielderror />
我们上传一个错误类型的文件,发现:
如果要自定义消息内容的话:
我们就要加入消息资源文件了,首先在struts.xml中加入:
<constant name="struts.custom.i18n.resources" value="Resource" />
关于key的来源和占位符的替代值可以参看fileupload拦截器的源代码的acceptFile方法
同时上传多个文件:
同时上传多个文件和上传单个文件的过程是一模一样的,只不过要满足以下条件:
1.前台可以将多个文件域的name属性设置成一样
2.在action中用数组或List来接收前台的File
3.循环数组或list,对每个File对象进行操作
文件的下载:
Struts下载主要是配置好一个result,这个result的类型是“stream”类型的,可去struts-default.xml查找相应的源代码:这里只贴出下载的代码和配置:
Action
//告诉浏览器数据是以下载的形式接收
private String contentType="application/x-msdownload";
//告诉浏览器数据将要下载的文件的文件名
private String contentDisposition="attachment;filename=";
//设置服务器读取文件的缓冲区大小
private String bufferSize="2048";
//前台提交过来需要下载的文件的文件名、路径
private String fnamepath;
@Override
public String execute() throws Exception {
File temp = new File(fnamepath);
this.contentDisposition+=temp.getName();
return"down";
}
/**
* 此方法将文件多对应的读取流拿到,getFile是和配置文件中inputName对应的
*/
public InputStream getFile(){
return
ServletActionContext.getServletContext().getResourceAsStream("/userDatas/"+fnamepat h);
}
扩展:
下载前检查用户是否登录或者检查用户的下载积分够不够
提示:
在action中execute方法中返回“down”这个result之前,先检查session中user的相关属性。