Struts2拦截器之FileUploadInterceptor
一、它能做什么?
借助于这个拦截器我们可以实现文件的上传和下载功能。
理论部分:
struts2的文件上传下载功能也要依赖于Apache commons-fileupload和Apache commons-io两个开源项目,要使用上传功能就需要把它们引入到classpath中。
比如考虑上传文件,几个关键点就是可以传什么类型的文件?可以传多大的文件?传过来以后放哪儿?叫什么名字?
当文件上传过来的时候是放在一个临时目录里的,我们在Action中持有一个成员属性File,这个File指向的就是服务器存放上传文件的临时目录中的实际文件(临时目录中的文件不会长久保存)
这个是default.properties中默认的一些属性,不配置临时目录的话默认就是用javax.servlet.context.tempdir
# uses javax.servlet.context.tempdir by default
struts.multipart.saveDir=
struts.multipart.maxSize=2097152
可以在配置文件中使用配置常量,这个配置的常量是全局的,意思就是struts.multipart.saveDir表示所有上传的文件都临时保存在这个目录中,而struts.multipart.maxSize指的是整个项目的上传文件的最大的size不能超过多少。
而下面这个是在action下设置的,针对的是单个的Action级别的:
allowedExtensionsSet 允许的文件类型扩展名,基于扩展名检查并不是特别靠谱
allowedTypesSet 允许的文件类型
maximumSize 允许的文件大小,这个zhide是一次上传的文件大小的上限
二、如何做?
1. 单文件上传:
首先来一个最简单的用法,即一次上传一个文件,参数都使用默认值。
只需要写一个前端:
<form action="uploadAction" method="post" enctype="multipart/form-data">
<input type="file" name="file"/><br/>
<input type="submit" value="上传" />
</form>
然后定义Action:
public class UploadAction extends ActionSupport {
private File file; //与表单file控件的name一致,指向了服务器临时目录中的上传文件
private String fileContentType; //File变量的名+ContentType,表示文件的MIME类型
private String fileFileName; //File变量的名+FileName,表示文件上传之前的名称
@Override
public String execute() throws Exception {
System.out.println(file+" "+fileContentType+" "+fileFileName);
//do something...
return SUCCESS;
}
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public String getFileContentType() {
return fileContentType;
}
public void setFileContentType(String fileContentType) {
this.fileContentType = fileContentType;
}
public String getFileFileName() {
return fileFileName;
}
public void setFileFileName(String fileFileName) {
this.fileFileName = fileFileName;
}
}
Action中的三个变量:
File file : 对于单文件上传类型,这个文件的名字必须是File类型的并且变量的名字要和前端表单的文件控件的name属性一致,会给这个变量赋值指向处于服务器上传文件临时目录中的那个文件。
fileContentType :文件的MIME类型,比如image/jpeg,application/octet-stream之类的。
fileFileName : 文件名,文件在上传之前在客户端的磁盘上存在就必然有一个名字,这里就是那个名字。
总结一下单文件上传:
1.表单的enctype="multipart/form-data"属性。
2.Action的三个成员变量file(文件本身),fileContentType(文件MIME类型),fileFileName(文件名)。
2. 多文件上传
<form action="uploadAction" method="post" enctype="multipart/form-data">
<input type="file" name="file"/><br/>
<input type="file" name="file"/><br/>
<input type="submit" value="上传" />
</form>
Action:
public class UploadAction extends ActionSupport {
private File file[]; // 与表单file控件的name一致,指向了服务器临时目录中的上传文件
private String fileContentType[]; // File变量的名+ContentType,表示文件的MIME类型
private String fileFileName[]; // File变量的名+FileName,表示文件上传之前的名称
@Override
public String execute() throws Exception {
for(int i=0;i<file.length;i++){
System.out.println(file[i]+" "+fileContentType[i]+" "+fileFileName[i]);
}
// do something...
return SUCCESS;
}
public File[] getFile() {
return file;
}
public void setFile(File[] file) {
this.file = file;
}
public String[] getFileContentType() {
return fileContentType;
}
public void setFileContentType(String[] fileContentType) {
this.fileContentType = fileContentType;
}
public String[] getFileFileName() {
return fileFileName;
}
public void setFileFileName(String[] fileFileName) {
this.fileFileName = fileFileName;
}
}
或者:
public class UploadAction extends ActionSupport {
private List<File> file; // 与表单file控件的name一致,指向了服务器临时目录中的上传文件
private List<String> fileContentType; // File变量的名+ContentType,表示文件的MIME类型
private List<String> fileFileName; // File变量的名+FileName,表示文件上传之前的名称
@Override
public String execute() throws Exception {
for (int i = 0; i < file.size(); i++) {
System.out.println(file.get(i) + " " + fileContentType.get(i) + " "
+ fileFileName.get(i));
}
// do something...
return SUCCESS;
}
public List<File> getFile() {
return file;
}
public void setFile(List<File> file) {
this.file = file;
}
public List<String> getFileContentType() {
return fileContentType;
}
public void setFileContentType(List<String> fileContentType) {
this.fileContentType = fileContentType;
}
public List<String> getFileFileName() {
return fileFileName;
}
public void setFileFileName(List<String> fileFileName) {
this.fileFileName = fileFileName;
}
}
多文件上传的要点就是在单文件上传的基础上前端多个名字相同的表单文件域,Action接收的地方改成File[]数组或者List<File>集合都可以。
3. 文件下载
配置文件:
<?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>
<package name="default" namespace="/" extends="struts-default" >
<action name="downloadAction" class="struts_practice_001.DownloadAction">
<!-- 要将结果类型设置为stream -->
<result type="stream">
<!-- inputName跟Action中的输入流的名字要相同 -->
<param name="inputName">file</param>
<!-- contentDisposition的attachment表示让浏览器的默认行为是保存文件,而filename是保存文件的时候的默认名字 -->
<param name="contentDisposition">attachment;filename="psd.jpg"</param>
</result>
</action>
</package>
</struts>
Action:
public class DownloadAction extends ActionSupport {
private InputStream file; //将要下载的文件读到这个输入流中
@Override
public String execute() throws Exception {
file=ServletActionContext.getServletContext().getResourceAsStream("psb.jpg");
return SUCCESS;
}
public InputStream getFile() {
return file;
}
public void setFile(InputStream file) {
this.file = file;
}
}
文件下载的关键点:
1. Action中有一个InputStream,里面是要被下载的文件的流。
2.配置文件中配置一个为stream类型的结果,传入两个参数:inputName跟Action的InputStream名字保持一致,contentDisposition是给浏览器看的提示。
4.配置参数详解
<struts>
<!-- 文件上传到服务器的临时目录 -->
<constant name="struts.multipart.saveDir" value="/tempUpload"></constant>
<!-- 允许的文件最大尺寸(全局) -->
<constant name="struts.multipart.maxSize" value="1024000000"></constant> <package name="default" namespace="/" extends="struts-default" >
<action name="uploadAction" class="struts_practice_001.UploadAction">
<result>/success.jsp</result>
<interceptor-ref name="fileUpload">
<!-- 允许的MIME类型 -->
<param name="allowedTypes">image/bmp,image/png,image/gif,image/jpeg</param>
<!-- 允许上传文件的最大尺寸 -->
<param name="maximumSize">1024000</param>
</interceptor-ref>
<!-- 一定要写在后面 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
</package>
</struts>
这里有一点关于参数上的疑问,就是<constant name="struts.multipart.saveDir" value="/tempUpload" />我这样写的话这个目录究竟保存到了哪里呢?看别的博客上说的是

发现我的也是保存到了E盘上,但是这种说法很没有是根本没有说服力,设想一下如果让我们来设计的话,肯定要优先保存到剩余可用空间最大的分区上啦。
如果路径没有以/开头的话就是保存到user.dir。
参考资料:Struts2中的struts.multipart.saveDir的配置
三、原理是啥?
。。。。好长,以后闲下来再慢慢分析源码吧。。。
(没错,就这么太监了.....我发现写东西是件很奇妙的事情,有的时候连着写好几个小时感觉很爽,有的时候写不到十分钟就感觉头和蛋一起疼明明写不出来还硬要使劲挤牙膏....o(╯□╰)o)
Struts2拦截器之FileUploadInterceptor的更多相关文章
- Struts2拦截器之ModelDrivenInterceptor
叙述套路: 1.这是个啥东西,它是干嘛用的? 2.我知道它能干啥了,那它咋个用呢? 3.它能跑起来了,但是它是咋跑起来的是啥原理呢? 一.ModelDriven是个啥?他能做什么? 从前端页面到后端的 ...
- Struts2拦截器之DefaultWorkflowInterceptor
一.DefaultWorkflowInterceptor是什么 首先说这东西是干嘛来的,在action中可以对传进来的数据进行验证,方法是实现Validateable接口的validate():voi ...
- Struts2拦截器之ExceptionMappingInterceptor(异常映射拦截器)
一.异常拦截器是什么? 异常拦截器的作用是提供一个机会,可以设置在action执行过程中发生异常的时候映射到一个结果字符串而不是直接中断. 将异常整合到业务逻辑中,比如在分层系统的调用中可以从底层抛出 ...
- Struts2拦截器的执行过程浅析
在学习Struts2的过程中对拦截器和动作类的执行过程一度陷入误区,特别读了一下Struts2的源码,将自己的收获分享给正在困惑的童鞋... 开始先上图: 从Struts2的图可以看出当浏览器发出请求 ...
- Struts2拦截器总结<转>
由于项目中在登录跳转到其他应用程序模块的时候有用到拦截器,因此查看了一下相关资料. 原文地址:http://blog.csdn.net/sendfeng/article/details/4248120 ...
- Struts2 拦截器具体配置过程
拦截器差点儿遍布每个程序中,所以贴出拦截器配置的具体过程,希望可以帮到大家. Struts2 拦截器具体配置过程 <interceptors> <!-- 先定义拦截器 --> ...
- Struts2拦截器详解
一.Struts2拦截器原理: Struts2拦截器的实现原理相对简单,当请求struts2的action时,Struts 2会查找配置文件,并根据其配置实例化相对的 拦截器对象,然后串成一个列 ...
- 转载 - Struts2 拦截器详细配置过程
出处:http://www.blogjava.net/zzzlyr/archive/2009/10/12/297998.html Struts2 拦截器详细配置过程 1:所有拦截器的超级接口Inter ...
- Struts2 拦截器配置以及实现
@(Java ThirdParty)[Struts|Interceptor] Struts2 拦截器配置以及实现 Struts2的拦截器应用于Action,可以在执行Action的方法之前,之后或者两 ...
随机推荐
- 微软“One Windows”的梦想已经破灭了吗?
导读 Windows 10 正式公布的时候,微软曾表示该系统将开启更为个性化的计算新纪元,可让用户在使用各类设备处理各项事务时,享受到一致.熟悉和可兼容的体验,从 Xbox 到 PC 和手机,再到平板 ...
- hiho #1284 机会渺茫
#1284 : 机会渺茫 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi最近在追求一名学数学的女生小Z.小Z其实是想拒绝他的,但是找不到好的说辞,于是提出了这样的要 ...
- memcache 与 mencached扩展的区别
memcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的.需要频繁访问数据库的网站访问速 ...
- Tomcat配置文件server.xml详解
<?xml version='1.0' encoding='utf-8'?> <Server port="8005" shutdown="SHUTDOW ...
- php preg_match($p, $str, $match)方法简介
方法作用:匹配指定的正则表达式并将结果放在$match数组中 代码示例: $p = '/name:([\\ws]+)/'; $str = "name:steven jobs"; p ...
- SQL Server 2012 自动增长列,值跳跃问题
介绍 从 SQL Server 2012 版本开始, 当SQL Server 实例重启之后,表格的自动增长列的值会发生跳跃,而具体的跳跃值的大小是根据增长列的数据类型而定的.如果数据类型是 整型(in ...
- sruts2 自定义类型转换器
1.1.1 Struts2中自定义类型转换器:(了解) 类型转换的过程是双向的过程: JSP---->Action参数提交:String---Date. Action---->JSP ...
- javascript 解析dom字符串
知识要求:1:熟悉dom结构层次(如childNodes,nodeType,parent,children)等. 2:熟悉jq对象转换js 对象,反之 毕竟不是专业js人.借助第3方框架.其实jq也是 ...
- Qt 改变图片大小
void Setting_TabProduct::changeImageSize(int width,int height,QString imgFile) { QPixmap pixmap(imgF ...
- ACM/ICPC 之 DFS求解欧拉回路+打表(POJ1392)
本题可以通过全部n位二进制数作点,而后可按照某点A的末位数与某点B的首位数相等来建立A->B有向边,以此构图,改有向图则是一个有向欧拉回路,以下我利用DFS暴力求解该欧拉回路得到的字典序最小的路 ...