Struts2下多文件的上传与下载
目录
多文件 上传 下载 随意文件java Struts2单例 配置 动态读取 李顺利
在网络上,对于Java处理文件上传和下载的技术比较多,而Struts作为一款优秀的框架也提供了非常方便的文件上传和下载,而网上的一些例程都非常的不全面,概括来:
1)文件上传比较多,多文件上传少一点
2)文件下载很少的,看似简单,实则不然
3)文件下载一般都是单文件或者固定的文件,并没有(很少)实现随意文件的下载的例子
最近也在研究一下文件的上传和下载,在整合网上、浪曦风中叶老师和自己的学习的思想,写了这个工程,提供给大家参考,所以的代码终在IE、FireFox、Chrome测试通过。
1.能够对多个文件进行上传(可以选择上传文件个数,也即上传文件个数不定)
2.能够对上传路径进行配置文件(upload.properties)指定,使用了一些类似单例模式的静态代码块
3.对配置文件中的路径可以进行动态读取(不重启服务器)
4.Struts2进行下载处理,能对上传的所有文件进行下载(多个)
5.文件保存的名称UUID生成,不过显示并下载的名称都是原文件名称
(人性化,通过UploadFiles处理)
最新的Struts2:struts-2.1.8、MyEclipse、Tomcat、IE、FireFox、Chrome
…
struts2
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
…
在web.xml中使用了最新的Struts2的中央处理器类org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter,而不再是以前的org.apache.struts2.dispatcher.FilterDispatcher,FilterDispatcher在新版本Struts2中已经标注为过时了,请大家尽量使用最新的filter。
/p>
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
/upload.jsp
/upload.jsp
/download.jsp
attachment;filename="${fileName}"
downloadFile
就是文件上传和下载的一些Struts2配置,注意上传的时候,请引入
,
下载的配置中注意:downloadFile
其他的配置解释网上很多,不懂的可以先google学习一下。
在此文件中请注意文件数组的使用,因为是多文件
packageorg.usc.file;
importjava.io.File;
importjava.util.ArrayList;
importjava.util.List;
importjava.util.UUID;
importorg.apache.commons.io.FileUtils;
importorg.apache.struts2.ServletActionContext;
importorg.usc.utils.UploadConfigurationRead;
importcom.opensymphony.xwork2.ActionSupport;
/**
*多文件上传类
*
*@authorMZ
*
*@Time2009-11-24下午09:26:44
*/
publicclassUploadActionextendsActionSupport
{
/**
*
*/
privatestaticfinallongserialVersionUID= 1L;
privateFile[]upload;//实际上传文件
privateString[]uploadContentType;//文件的内容类型
privateString[]uploadFileName;//上传文件名
privateListuploadFiles=newArrayList();
publicString execute()throwsException
{
try
{
String targetDirectory = ServletActionContext.getServletContext()
.getRealPath("/"+ UploadConfigurationRead.getInstance().getConfigItem("uploadFilePath").trim());//获得路径
for(inti = 0; i
{
String fileName =uploadFileName[i];//上传的文件名
String type =uploadContentType[i];//文件类型
String realName = UUID.randomUUID().toString()+ getExt(fileName);//保存的文件名称,使用UUID+后缀进行保存
File target =newFile(targetDirectory, realName);
FileUtils.copyFile(upload[i], target);//上传至服务器的目录,一般都这样操作,
//在把路径写入数据库即可
UploadFiles uf =newUploadFiles();//创建文件
uf.setUploadContentType(type);
uf.setUploadFileName(fileName);
uf.setUploadRealName(realName);
uploadFiles.add(uf);//添加到需要下载文件的List集合中
}
ServletActionContext.getRequest().setAttribute("uploadFiles",
uploadFiles);
}catch(Exception e)
{
e.printStackTrace();
addActionError(e.getMessage());
returnINPUT;
}
returnSUCCESS;
}
publicFile[] getUpload()
{
returnupload;
}
publicvoidsetUpload(File[] upload)
{
this.upload= upload;
}
publicString[] getUploadContentType()
{
returnuploadContentType;
}
publicvoidsetUploadContentType(String[] uploadContentType)
{
this.uploadContentType= uploadContentType;
}
publicString[] getUploadFileName()
{
returnuploadFileName;
}
publicvoidsetUploadFileName(String[] uploadFileName)
{
this.uploadFileName= uploadFileName;
}
publicstaticString getExt(String fileName)
{
returnfileName.substring(fileName.lastIndexOf("."));
}
}
在此文件中要注意publicInputStream getDownloadFile()的名称在Struts2配置文件配置,返回的是一个InputStream类型的对象。
packageorg.usc.file;
importjava.io.InputStream;
importjava.io.UnsupportedEncodingException;
importcom.opensymphony.xwork2.ActionSupport;
importorg.apache.struts2.ServletActionContext;
importorg.usc.utils.UploadConfigurationRead;
publicclassDownloadActionextendsActionSupport
{
privatestaticfinallongserialVersionUID= 6329383258366253255L;
privateStringfileName;
privateStringfileRealName;
publicvoidsetFileName()
{
//得到请求下载的文件名
String fname = ServletActionContext.getRequest().getParameter("name");
String frealname = ServletActionContext.getRequest().getParameter("realname");
try
{
/*
*对fname参数进行UTF-8解码,注意:实际进行UTF-8解码时会使用本地编码,本机为GBK。
*这里使用request.setCharacterEncoding解码无效.
*只有解码了getDownloadFile()方法才能在下载目录下正确找到请求的文件
*/
fname =newString(fname.getBytes("ISO-8859-1"),"UTF-8");
frealname=newString(frealname.getBytes("ISO-8859-1"),"UTF-8");
}catch(Exception e)
{
e.printStackTrace();
}
this.fileName= fname;
this.fileRealName= frealname;
//System.out.println(fileName);
//System.out.println(fileRealName);
}
/*
* @getFileName此方法对应的是struts.xml文件中的:
* name="contentDisposition">attachment;filename="${fileName}"
*这个属性设置的是下载工具下载文件时显示的文件名,要想正确的显示中文文件名,我们需要对fileName再次编码
*否则中文名文件将出现乱码,或无法下载的情况
*/
publicString getFileName()throwsUnsupportedEncodingException
{
fileRealName=newString(fileRealName.getBytes(),"ISO-8859-1");
returnfileRealName;
}
/*
* @getDownloadFile此方法对应的是struts.xml文件中的:
* name="inputName">downloadFile返回下载文件的流,可以参看struts2的源码
*/
publicInputStream getDownloadFile()
{
this.setFileName();
returnServletActionContext.getServletContext().getResourceAsStream("/"+UploadConfigurationRead.getInstance().getConfigItem("uploadFilePath").trim()+"/"+fileName);
}
@Override
publicString execute()throwsException
{
returnSUCCESS;
}
}
动态读取配置文件,借鉴网上的代码
packageorg.usc.utils;
importjava.io.File;
importjava.io.FileInputStream;
importjava.net.URI;
importjava.net.URISyntaxException;
importjava.util.Properties;
/**
*动态读取配置文件类
*
*@authorMZ
*
*@Time2009-11-24下午08:25:22
*/
publicclassUploadConfigurationRead {
/**
*属性文件全名,需要的时候请重新配置PFILE
*/
privatestaticStringPFILE="upload.properties";
/**
*配置文件路径
*/
privateURIuri=null;
/**
*属性文件所对应的属性对象变量
*/
privatelongm_lastModifiedTime= 0;
/**
*对应于属性文件的文件对象变量
*/
privateFilem_file=null;
/**
*属性文件所对应的属性对象变量
*/
privatePropertiesm_props=null;
/**
*唯一实例
*/
privatestaticUploadConfigurationReadm_instance=newUploadConfigurationRead();
/**
*私有构造函数
*
*@throwsURISyntaxException
*/
privateUploadConfigurationRead() {
try{
m_lastModifiedTime= getFile().lastModified();
if(m_lastModifiedTime== 0) {
System.err.println(PFILE+"file does not exist!");
}
m_props=newProperties();
m_props.load(newFileInputStream(getFile()));
}catch(URISyntaxException e) {
System.err.println(PFILE+"文件路径不正确");
e.printStackTrace();
}catch(Exception e) {
System.err.println(PFILE+"文件读取异常");
e.printStackTrace();
}
}
/**
*查找ClassPath路径获取文件
*
*@returnFile对象
*@throwsURISyntaxException
*/
privateFile getFile()throwsURISyntaxException {
URI fileUri =this.getClass().getClassLoader().getResource(PFILE).toURI();
m_file=newFile(fileUri);
returnm_file;
}
/**
*静态工厂方法
*
*@return返回ConfigurationRead的单一实例
*/
publicsynchronizedstaticUploadConfigurationRead getInstance() {
returnm_instance;
}
/**
*读取一特定的属性项
*/
publicString getConfigItem(String name, String defaultVal) {
longnewTime =m_file.lastModified();
//检查属性文件是否被修改
if(newTime == 0) {
//属性文件不存在
if(m_lastModifiedTime== 0) {
System.err.println(PFILE+" file does not exist!");
}else{
System.err.println(PFILE+" file was deleted!!");
}
returndefaultVal;
}elseif(newTime >m_lastModifiedTime) {
m_props.clear();
try{
m_props.load(newFileInputStream(getFile()));
}catch(Exception e) {
System.err.println("文件重新读取异常");
e.printStackTrace();
}
}
m_lastModifiedTime= newTime;
String val =m_props.getProperty(name);
if(val ==null) {
returndefaultVal;
}else{
returnval;
}
}
/**
*读取一特定的属性项
*
*@paramname
*属性项的项名
*@return属性项的值(如此项存在),空(如此项不存在)
*/
publicString getConfigItem(String name) {
returngetConfigItem(name,"");
}
}
在IE(遨游)中多文件上传
在IE(遨游)中多文件下载
在Firefox中多文件上传
在Firefox中多文件下载
在Chrome中多文件上传
在Chrome中多文件下载
服务器中所以文件
为了有更好得兼容性,这个小demo已经移植到用maven构建(有些网页反映在eclipse里面部署失败),你可以下载上面的标记为maven的源码,或者通过
svn checkouthttp://usc.googlecode.com/svn/trunk/multi-files-upload-and-download/
or
git clone git://github.com/lishunli/multi-files-upload-and-download.git
or
forkhttps://github.com/lishunli/multi-files-upload-and-download后,自己进行maven install并部署。
实际上,这个还可以进行扩展,可以存取上传的文件名和路径到数据库中,再在UI(jsp)上面根据需求进行显示文件,并提供下载,仅抛下砖头了,其它的...如果有什么建议或意见可以通过Q:506817493或E:leeshunliqq.com,大家一起交流。
顺利写于2009年11月24日
最后更新于2013年4月12日
博客中的一些下载已经放到了百度云了,请根据需要下载。【点我去百度云下载】
最后弱弱地说一下,如果可以的话,转载请提供出处(
),谢谢。
posted on 2010-01-07 21:21 李顺利 阅读(26832) 评论(38) 编辑 收藏