在做B/S系统时,通常会涉及到上传文件和下载文件,在没接struts2框架之前,我们都是使用apache下面的commons子项目的FileUpload组件来进行文件的上传,但是那样做的话,代码看起来比较繁琐,而且不灵活,在学习了struts2后,struts2为文件上传下载提供了更好的实现机制,在这里我分别就单文件上传和多文件上传的源代码进行一下讲解,这里需要导入文件下载上传的两个jar文件,一个是commons-fileupload-1.2.2.jar,另一个是commons-io-2.0.1.jar

struts2单文件上传:

首先是一个jsp文件上传页面,这个比较简单,就是一个表单,里面有个文件上传框

   <!--在进行文件上传时,表单提交方式一定要是post的方式,因为文件上传时二进制文件可能会很大,还有就是enctype属性,这个属性一定要写成multipart/form-data,
  不然就会以二进制文本上传到服务器端-->
  <form action="fileUpload.action" method="post" enctype="multipart/form-data">
  
username: <input type="text" name="username"><br>
file: <input type="file" name="file"><br> <input type="submit" value="submit">
</form>

原理是就是struts2的FileUploadInterceptor拦截器过滤。

接下来是FileUploadAction部分代码,因为struts2对上传和下载都提供了很好的实习机制,所以在action这段我们只需要写很少的代码就行:

Action中文件属性的命名规则约定,在struts2内部的的FileUploadInterceptor.class完成的

String[] fileName = multiWrapper.getFileNames(inputName);//得到请求的所有文件名

if (isNonEmpty(fileName)) { 
                    // get a File object for the uploaded File 
                    File[] files = multiWrapper.getFiles(inputName); 
                    if (files != null && files.length > 0) { 
                        List<File> acceptedFiles = new ArrayList<File>(files.length); 
                        List<String> acceptedContentTypes = new ArrayList<String>(files.length); 
                        List<String> acceptedFileNames = new ArrayList<String>(files.length); 
                        String contentTypeName = inputName + "ContentType";//默认就是input名称+ContentType 
                        String fileNameName = inputName + "FileName";//默认就是input名称+FileName

for (int index = 0; index < files.length; index++) { 
                            if (acceptFile(action, files[index], fileName[index], contentType[index], inputName, validation, ac.getLocale())) { 
                                acceptedFiles.add(files[index]); 
                                acceptedContentTypes.add(contentType[index]); 
                                acceptedFileNames.add(fileName[index]); 
                            } 
                        }

if (!acceptedFiles.isEmpty()) { 
                            Map<String, Object> params = ac.getParameters();//添加到parameters中 这样就可以通过OGNL注入到action了

params.put(inputName, acceptedFiles.toArray(new File[acceptedFiles.size()])); 
                            params.put(contentTypeName, acceptedContentTypes.toArray(new String[acceptedContentTypes.size()])); 
                            params.put(fileNameName, acceptedFileNames.toArray(new String[acceptedFileNames.size()])); 
                        } 
                    }

public class FileUploadAction extends ActionSupport
{
private String username;

   //注意,file并不是指前端jsp上传过来的文件本身,而是文件上传过来存放在临时文件夹下面的文件,还有就是file变量的命名是和对应jsp的name属性值一样的。
private File file; //提交过来的file的名字
private String fileFileName; //提交过来的file的MIME类型
private String fileContentType; public String getUsername()
{
return username;
} public void setUsername(String username)
{
this.username = username;
} public File getFile()
{
return file;
} public void setFile(File file)
{
this.file = file;
} public String getFileFileName()
{
return fileFileName;
} public void setFileFileName(String fileFileName)
{
this.fileFileName = fileFileName;
} public String getFileContentType()
{
return fileContentType;
} public void setFileContentType(String fileContentType)
{
this.fileContentType = fileContentType;
} @Override
public String execute() throws Exception
{
String root = ServletActionContext.getServletContext().getRealPath("/upload"); InputStream is = new FileInputStream(file); OutputStream os = new FileOutputStream(new File(root, fileFileName));
//也可以这么写
       //String root = ServletActionContext.getServletContext().getRealPath("/upload"+fileFileName); 
//OutputStream os = new FileOutputStream(root);
System.out.println("fileFileName: " + fileFileName);

    // 因为file是存放在临时文件夹的文件,我们可以将其文件名和文件路径打印出来,看和之前的fileFileName是否相同
System.out.println("file: " + file.getName());
System.out.println("file: " + file.getPath()); byte[] buffer = new byte[500];
int length = 0; while(-1 != (length = is.read(buffer, 0, buffer.length)))
{
os.write(buffer);
} os.close();
is.close(); return SUCCESS;
}
}

自己写的例子:

<form action="upload" method="post" enctype="multipart/form-data">

     <input  type="file" name="file" value="文件上传"><br>

     <input  type="submit" value="提交">
</form>

  


package action;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import javax.servlet.ServletContext;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class UploadAction extends ActionSupport {

/**
*
*/
private static final long serialVersionUID = 1L;
private File file;
private String fileContentType;
private String fileFileName;

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;
}

@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
System.out.println("file:"+file);
System.out.println("fileContentType:"+fileContentType);
System.out.println("fileFileName:"+fileFileName);

ServletContext ctx=ServletActionContext.getServletContext();
/*String dir=ctx.getRealPath("/files/"+fileFileName);
new File(dir).getParentFile().mkdir();
FileOutputStream out=new FileOutputStream(dir);*/
String dir=ctx.getRealPath("/files");
new File(dir).mkdir();
FileOutputStream out=new FileOutputStream(dir+"/"+fileFileName);
System.out.println(dir+"/"+fileFileName);
FileInputStream in=new FileInputStream(file);
byte[] buffer=new byte[1024];
int len=0;
while((len=in.read(buffer))!=-1){
out.write(buffer,0,len);
}
out.close();
in.close();

return super.execute();
}

}

  

首先我们要清楚一点,这里的file并不是真正指代jsp上传过来的文件,当文件上传过来时,struts2首先会寻找struts.multipart.saveDir(这个是在default.properties里面有)这个name所指定的存放位置,我们可以新建一个struts.properties属性文件来指定这个临时文件存放位置,如果没有指定,那么文件会存放在tomcat的apache-tomcat-7.0.29\work\Catalina\localhost\目录下,然后我们可以指定文件上传后的存放位置,通过输出流将其写到流里面就行了,这时我们就可以在文件夹里看到我们上传的文件了。

文件上传后我们还需要将其下载下来,其实struts2的文件下载原理很简单,就是定义一个输入流,然后将文件写到输入流里面就行,关键配置还是在struts.xml这个配置文件里配置:

FileDownloadAction代码如下:

public class FileDownloadAction extends ActionSupport
{
public InputStream getDownloadFile()
{
return ServletActionContext.getServletContext().getResourceAsStream("upload/通讯录2012年9月4日.xls");
} @Override
public String execute() throws Exception
{
return SUCCESS;
}
}

我们看,这个action只是定义了一个输入流,然后为其提供getter方法就行,接下来我们看看struts.xml的配置文件:

        <action name="fileDownload" class="com.xiaoluo.struts2.FileDownloadAction">
<result name="success" type="stream">
<param name="contentDisposition">attachment;filename="通讯录2012年9月4日.xls"</param>
<param name="inputName">downloadFile</param>
</result>
</action>

struts.xml配置文件有几个地方我们要注意,首先是result的类型,以前我们定义一个action,result那里我们基本上都不写type属性,因为其默认是请求转发(dispatcher)的方式,除了这个属性一般还有redirect(重定向)等这些值,在这里因为我们用的是文件下载,所以type一定要定义成stream类型,告诉action这是文件下载的result,result元素里面一般还有param子元素,这个是用来设定文件下载时的参数,inputName这个属性就是得到action中的文件输入流,名字一定要和action中的输入流属性名字相同,然后就是contentDisposition属性,这个属性一般用来指定我们希望通过怎么样的方式来处理下载的文件,如果值是attachment,则会弹出一个下载框,让用户选择是否下载,如果不设定这个值,那么浏览器会首先查看自己能否打开下载的文件,如果能,就会直接打开所下载的文件,(这当然不是我们所需要的),另外一个值就是filename这个就是文件在下载时所提示的文件下载名字。在配置完这些信息后,我们就能过实现文件的下载功能了。

struts2多文件上传:

其实多文件上传和单文件上传原理一样,单文件上传过去的是单一的File,多文件上传过去的就是一个List<File>集合或者是一个File[]数组,首先我们来看一下前端jsp部分的代码,这里我用到了jquery来实现动态的添加文件下载框以及动态的删除下载框:

    <script type="text/javascript" src="script/jquery-1.8.1.js"></script>
<script type="text/javascript"> $(function()
{
$("#button").click(function()
{
var html = $("<input type='file' name='file'>");
var button = $("<input type='button' name='button' value='删除'><br>"); $("#body div").append(html).append(button); button.click(function()
{
html.remove();
button.remove();
})
})
}) </script>
</head> <body id="body"> <form action="fileUpload2.action" method="post" enctype="multipart/form-data"> username: <input type="text" name="username"><br>
file: <input type="file" name="file">
<input type="button" value="添加" id="button"><br>
<div></div>
<input type="submit" value="submit"> </form> </body>

file的名字必须都命名成file才行,然后处理多文件上传的action代码如下:

public class FileUploadAction2 extends ActionSupport
{
private String username;

  //这里用List来存放上传过来的文件,file同样指的是临时文件夹中的临时文件,而不是真正上传过来的文件
private List<File> file;

  //这个List存放的是文件的名字,和List<File>中的文件相对应
private List<String> fileFileName; private List<String> fileContentType; public String getUsername()
{
return username;
} public void setUsername(String username)
{
this.username = username;
} public List<File> getFile()
{
return file;
} public void setFile(List<File> file)
{
this.file = file;
} public List<String> getFileFileName()
{
return fileFileName;
} public void setFileFileName(List<String> fileFileName)
{
this.fileFileName = fileFileName;
} public List<String> getFileContentType()
{
return fileContentType;
} public void setFileContentType(List<String> fileContentType)
{
this.fileContentType = fileContentType;
} @Override
public String execute() throws Exception
{
String root = ServletActionContext.getServletContext().getRealPath("/upload"); for(int i = 0; i < file.size(); i++)
{
InputStream is = new FileInputStream(file.get(i)); OutputStream os = new FileOutputStream(new File(root, fileFileName.get(i))); byte[] buffer = new byte[500]; @SuppressWarnings("unused")
int length = 0; while(-1 != (length = is.read(buffer, 0, buffer.length)))
{
os.write(buffer);
} os.close();
is.close();
} return SUCCESS;
}
}

这样同样将其写到一个输出流里面,这样我们就可以在文件夹里看到上传的多个文件了

接下来的文件下载就和刚才的文件下载一模一样,struts.xml也是一样的,这里就不再重复了

总结:总的来说,struts2提供的文件上传下载机制简化了我们很多代码,我们可以在以后的项目中使用该机制,同样我们也可以使用FileUpload组件来进行文件的上传,这个都是因个人爱好决定!

struts2的文件上传的更多相关文章

  1. jsp\struts1.2\struts2 中文件上传(转)

    jsp\struts1.2\struts2 中文件上传 a.在jsp中简单利用Commons-fileupload组件实现 b.在struts1.2中实现c.在sturts2中实现现在把Code与大家 ...

  2. Struts2+Uploadify文件上传使用详解

    Uploadify是JQuery的一个上传插件,实现的效果非常不错,带进度显示.不过官方提供的实例是php版本的,本文将详细介绍Uploadify在java中的使用,您也可以点击下面的链接进行演示或下 ...

  3. Struts2 多文件上传

    Struts2多文件上传只需要将 单文件上传中的File变成File[]  即可,上篇文章:单文件上传 <form action="${pageContext.request.cont ...

  4. Struts2图片文件上传,判断图片格式和图片大小

    1. 配置Struts2能够上传的最大文件大小 使用Struts2进行文件上传的时候,Struts2默认文件大小最大为2MB,如果要传大一点的文件,就需要修改struts.xml配置文件,重新设置能够 ...

  5. Struts2实现文件上传下载功能(批量上传)

    今天来发布一个使用Struts2上传下载的项目, struts2为文件上传下载提供了好的实现机制, 首先,可以先看一下我的项目截图 关于需要使用的jar包,需要用到commons-fileupload ...

  6. Struts2实现文件上传(四)

    Struts2实现文件上传 配置文件struts.xml <!-- /* * $Id: struts.xml 1364077 2012-07-21 12:57:02Z lukaszlenart ...

  7. Struts2实现文件上传(三)

    Struts2实现文件上传 配置文件web.xml <?xml version="1.0" encoding="UTF-8"?> <web-a ...

  8. Struts2实现文件上传(二)

    Struts2实现文件上传 文件上传页面 file.jsp: <%@ page language="java" import="java.util.*" ...

  9. Struts2实现文件上传(一)

    Struts2实现文件上传 文件上传成功后结果页面 result.jsp: <%@ page language="java" import="java.util.* ...

随机推荐

  1. MySQL_订单类型细分_20161222

    #目前在做一个各城市日订单角度的对比分析,因此需要对订单类型进行一下规整.由于App上产品活动许多,查询了多个表,将订单类型规则进行了统一,优惠券和满减券不能同时使用,创建的这两个表都是以订单ID为k ...

  2. 关于 Integer 的一个坑

    其实 JDK 中有很多小坑, 我们稍微不注意, 就掉进去了, 然后调了半天 bug, 也不知道为何. 很闹心! 这里说一下, 在Integer中的一个小坑. 看一个小例子: @Test public ...

  3. favicon.ico应用与正则表达式验证邮箱(可自动删除前后的空格)

    1.favicon.ico制作:favicon.ico可以ps制作;“shortcut icon”中间有一个空格 <head> <link rel="shortcut ic ...

  4. springmvc spring mybatis插入mysql中文乱码

    springmvc 插入mysql数据库中文乱码问题: 1.将页面中的编码改成utf-8 2.用SQLyog右击->改变数据库 以上两步可以保证页面数据编码一致 3.在mybatis连接的地方加 ...

  5. ORACLE连接SQLSERVER

    一.实验(实验成功) 1.实验目标:ORACLE连接SQLSERVER以及查询数据 2.搭建的环境: oracle 9i 9.0.2.0.1 地址:192.168.40.139 sql2000 的数据 ...

  6. 使用Graph工具观察FFT波形

    2014年8月1日,经过很长时间的上网查阅资料,走了很多弯路,终于可以成功使用Graph工具仿真波形了,虽然这个的确很简单,但是经过自己摸索出来的,兴奋之情难于言表. 明天就是七夕了,刚和女朋友分手的 ...

  7. 一步一步学WebSocket(二) 使用SuperWebSocket实现自己的服务端

    上一篇文章,我们了解了客户端如何与服务器创建WebSocket连接.但是一个巴掌拍不响,既然是通信,就必然最少要有两个端.今天我们来看看c#如何用已有的框架实现一个WebSocket服务端. 在.Ne ...

  8. CentOS6.5中配置Rabbitmq3.6.6集群方案

    一.安装Erlang环境 1.下载erlang源代码 wget http://erlang.org/download/otp_src_19.1.tar.gz 2.安装依赖相关库文件 yum insta ...

  9. jquery blockui 遮罩

    参考 : http://bookshadow.com/weblog/2014/09/26/jquery-blockui-js-introduction/ blockUI.html blockUI.ht ...

  10. otter双主同步安装与配置

    otter是阿里的开源数据同步项目,资源地址就不用说了哈,网上找,阿里云论坛关于单方向同步的配置已经很清楚了,理论上说,双主同步也不复杂,但是毕竟 是数据库,比较重要,配置双主的时候,总觉得心里没底, ...