一、它能做什么?

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

理论部分:

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. Knockout.Js案例二Working With Lists And Collections

    案例一:Foreach绑定 通常,您要生成重复的UI元素,特别是当显示列表,用户可以添加和删除元素.KO.JS让你轻松,使用的数组和foreach绑定. 在接下来的几分钟,您将构建一个动态UI保留席位 ...

  2. iOS开发——高级篇——地图 MapKit

    一.简介 1.在移动互联网时代,移动app能解决用户的很多生活琐事,比如周边:找餐馆.找KTV.找电影院等等导航:根据用户设定的起点和终点,进行路线规划,并指引用户如何到达 在上述应用中,都用到了定位 ...

  3. leetcode 173. Binary Search Tree Iterator

    Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the ro ...

  4. cocos2d内存管理

    设想如下场景, 这是一个典型的内存合理分配的场景: 在一帧内, 有若干个函数, 每个函数都会创建一系列的精灵, 每个精灵都不同, 都会占用一定的内存, 精灵的总数可能会有1000个, 而一个函数只会创 ...

  5. 如何优雅地使用 Sublime Text

    Sublime Text:一款具有代码高亮.语法提示.自动完成且反应快速的编辑器软件,不仅具有华丽的界面,还支持插件扩展机制,用她来写代码,绝对是一种享受.相比 于难于上手的Vim,浮肿沉重的Ecli ...

  6. 如何给ZenCart网站livezilla客服系统?

    大致步骤: 1 去官网下载livezilla

  7. Citrix运行检测出错

    Citrix运行检测出错: 出现意外错误.请确认服务器名称正确.服务器已打开.Citrix XenApp 已安装在服务器上并且 Citrix MFCOM 服务正在运行. 看Windows日志出现如下错 ...

  8. 代码高亮插件SyntaxHighlighter

    http://alexgorbatchev.com/SyntaxHighlighter/download/

  9. excle导入

    public function import_upload(){ set_time_limit(900); if(!empty($_FILES ['xls_path']['name'])){ $tmp ...

  10. window下安装mongodb及php mongo扩展

    1.安装mongoDB 下载最新版本的 MongoDB 下载地址:http://www.mongodb.org/downloads 解压文件到 D:\mongodb 解压后的文件列表如下: 创建数据存 ...