一、它能做什么?

借助于这个拦截器我们可以实现文件的上传和下载功能。

理论部分:

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的更多相关文章

  1. Struts2拦截器之ModelDrivenInterceptor

    叙述套路: 1.这是个啥东西,它是干嘛用的? 2.我知道它能干啥了,那它咋个用呢? 3.它能跑起来了,但是它是咋跑起来的是啥原理呢? 一.ModelDriven是个啥?他能做什么? 从前端页面到后端的 ...

  2. Struts2拦截器之DefaultWorkflowInterceptor

    一.DefaultWorkflowInterceptor是什么 首先说这东西是干嘛来的,在action中可以对传进来的数据进行验证,方法是实现Validateable接口的validate():voi ...

  3. Struts2拦截器之ExceptionMappingInterceptor(异常映射拦截器)

    一.异常拦截器是什么? 异常拦截器的作用是提供一个机会,可以设置在action执行过程中发生异常的时候映射到一个结果字符串而不是直接中断. 将异常整合到业务逻辑中,比如在分层系统的调用中可以从底层抛出 ...

  4. Struts2拦截器的执行过程浅析

    在学习Struts2的过程中对拦截器和动作类的执行过程一度陷入误区,特别读了一下Struts2的源码,将自己的收获分享给正在困惑的童鞋... 开始先上图: 从Struts2的图可以看出当浏览器发出请求 ...

  5. Struts2拦截器总结<转>

    由于项目中在登录跳转到其他应用程序模块的时候有用到拦截器,因此查看了一下相关资料. 原文地址:http://blog.csdn.net/sendfeng/article/details/4248120 ...

  6. Struts2 拦截器具体配置过程

    拦截器差点儿遍布每个程序中,所以贴出拦截器配置的具体过程,希望可以帮到大家. Struts2 拦截器具体配置过程 <interceptors> <!-- 先定义拦截器 --> ...

  7. Struts2拦截器详解

    一.Struts2拦截器原理: Struts2拦截器的实现原理相对简单,当请求struts2的action时,Struts 2会查找配置文件,并根据其配置实例化相对的    拦截器对象,然后串成一个列 ...

  8. 转载 - Struts2 拦截器详细配置过程

    出处:http://www.blogjava.net/zzzlyr/archive/2009/10/12/297998.html Struts2 拦截器详细配置过程 1:所有拦截器的超级接口Inter ...

  9. Struts2 拦截器配置以及实现

    @(Java ThirdParty)[Struts|Interceptor] Struts2 拦截器配置以及实现 Struts2的拦截器应用于Action,可以在执行Action的方法之前,之后或者两 ...

随机推荐

  1. 又一个绝对棒的对话框插件fancybox v1.3.4

    http://www.jsfoot.com/jquery/demo/2011-07-30/fancybox/index.html jquery插件:fancybox   Fancybox的特点如下: ...

  2. 以下css可以清除浮动

    .clearfix:after { content: ""; clear: both; visibility: hidden; display: block; height: 0p ...

  3. JSON字符串转JavaBean,net.sf.ezmorph.bean.MorphDynaBean cannot be cast to ……

    在json字符串转java bean时,一般的对象,可以直接转,如:一个学生类,属性有姓名.年龄等 public class Student implements java.io.Serializab ...

  4. Open CV缩放图像

    缩放图像是图像处理中需要经常使用的操作.太小的图像在图像识别中不能很好的处理,需要将其放大,太大的图像不方便储存,需要将其缩小,下面记录OpenCV图片缩放方法. 缩放函数 , , int inter ...

  5. C++基础知识(1)----文件操作

    参照 小菜鸟上校 的博客 // file operat.cpp : 定义控制台应用程序的入口点. /*上述例子的主要功能是将一个文件的内容复制到另一个文件中, 这个功能主要由一个函数copy来实现.它 ...

  6. linux 权限操作

    添加用户 命令格式:useradd 选项 用户名 -g 缺省组(不写则默认为用户名组) -G 所属组(添加到多个用户组,逗号隔开) -c 描述信息 -d 指定家目录 useradd –g aa bb ...

  7. ZJOI2014 2048

    Description 提交答案题,写个2048 AI 告诉你随机数生成方式. Sol xjblg+A*. 首先我写了个模拟,2048. 然后自己YY就可以啦...各种乱搞... 因为随机数,一个最好 ...

  8. BZOJ 1922: [Sdoi2010]大陆争霸

    Description 一个无向图,到一个点之前需要先到其他点,求从第一个点到第 \(n\) 点最短时间. Sol 拓扑+Dijkstra. 跑Dijkstra的时候加上拓扑序... 用两个数组表示 ...

  9. MY_FIRSH_MODULE

    模块描述 将30个字节的内存空间模仿成设备文件.每次读写不超过30个字节. 模块加载成功之后,需建立设备文件 mknod /dev/mydev c 231 0 模块代码 #include <li ...

  10. js的工作原理

    JavaScript就是所谓的客户端脚本语言,是一种在互联网浏览器(浏览器也称为Web客户端,因为它连接到Web服务器上,以下载页面)内部运行的计算机编程语言. 也就是说,如果一个网页里有js代码,那 ...