Struts2下多文件的上傳與下載

需求
1.能夠對多個文件進行上傳(可以選擇上傳文件個數,也即上傳文件個數不定)
2.能夠對上傳路徑進行配置文件(upload.properties)指定,使用了一些類似單例模式的靜態代碼塊
3.對配置文件中的路徑可以進行動態讀取(不重啓服務器)
4.Struts2進行下載處理,能對上傳的所有文件進行下載(多個)
5.文件保存的名稱UUID生成,不過顯示並下載的名稱都是原文件名稱
(人性化,通過UploadFiles處理)
環境
最新的Struts2:struts-2.1.8、MyEclipse、Tomcat、IE、FireFox、Chrome

目錄結構


重要文件的看點
web.xml

<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>

在web.xml中使用了最新的Struts2的中央處理器類org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter,而不再是以前的org.apache.struts2.dispatcher.FilterDispatcher,FilterDispatcher在新版本Struts2中已經標註爲過時了,請大家儘量使用最新的filter。
struts.xml
<?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>
<constant name="struts.i18n.encoding" value="utf8" />
<package name="file" namespace="/" extends="struts-default">
<action name="showUpload">
<result>/upload.jsp</result>
</action>
<action name="upload" class="org.usc.file.UploadAction">
<result name="input">/upload.jsp</result>
<!-- <result name="success">/upload_success.jsp</result>-->
<result name="success">/download.jsp</result>
<interceptor-ref name="fileUpload">
<!--大家可以設置成自己的配置,想文件類型和大小等限制 -->
<!-- <param name="maximumSize">2097152</param>單位是字節 2M (2097152B) -->
<!-- <param name="allowedTypes">image/bmp,image/x-png,image/png,image/gif,image/jpeg,image/jpg,image/pjpeg</param>-->
<!-- -->
<!-- 容許文件類型爲doc,ppt,xls,pdf,txt,java-->
<!-- -->
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
<action name="download" class="org.usc.file.DownloadAction">
<result name="success" type="stream">
<param name="contentDisposition">attachment;filename="${fileName}"</param>
<param name="inputName">downloadFile</param>
</result>
</action>
</package>
</struts>
就是文件上傳和下載的一些Struts2配置,注意上傳的時候,請引入
<interceptor-ref name="defaultStack"></interceptor-ref>,
下載的配置中注意:<param name="inputName">downloadFile</param>
其他的配置解釋網上很多,不懂的可以先google學習一下。
UploadAction
在此文件中請注意文件數組的使用,因爲是多文件
package org.usc.file;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import org.usc.utils.UploadConfigurationRead;
import com.opensymphony.xwork2.ActionSupport;
/**
* 多文件上傳類
*
* @author MZ
*
* @Time 2009-11-24下午09:26:44
*/
public class UploadAction extends ActionSupport
{
/**
*
*/
private static final long serialVersionUID = 1L;
private File[] upload;// 實際上傳文件
private String[] uploadContentType; // 文件的內容類型
private String[] uploadFileName; // 上傳文件名
private List<UploadFiles> uploadFiles = new ArrayList<UploadFiles>();
public String execute() throws Exception
{
try
{
String targetDirectory = ServletActionContext.getServletContext().getRealPath("/"+ UploadConfigurationRead.getInstance().getConfigItem("uploadFilePath").trim());// 獲得路徑
for (int i = 0; i < upload.length; i++)
{
String fileName = uploadFileName[i];// 上傳的文件名
String type = uploadContentType[i];// 文件類型
String realName = UUID.randomUUID().toString()+ getExt(fileName);// 保存的文件名稱,使用UUID+後綴進行保存
File target = new File(targetDirectory, realName);
FileUtils.copyFile(upload[i], target);// 上傳至服務器的目錄,一般都這樣操作,
// 在把路徑寫入數據庫即可
UploadFiles uf = new UploadFiles();// 創建文件
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());
return INPUT;
}
return SUCCESS;
}
public File[] getUpload()
{
return upload;
}
public void setUpload(File[] upload)
{
this.upload = upload;
}
public String[] getUploadContentType()
{
return uploadContentType;
}
public void setUploadContentType(String[] uploadContentType)
{
this.uploadContentType = uploadContentType;
}
public String[] getUploadFileName()
{
return uploadFileName;
}
public void setUploadFileName(String[] uploadFileName)
{
this.uploadFileName = uploadFileName;
}
public static String getExt(String fileName)
{
return fileName.substring(fileName.lastIndexOf("."));
}
}
DownloadAction
在此文件中要注意public InputStream getDownloadFile()的名稱在Struts2配置文件配置,返回的是一個InputStream類型的對象。
package org.usc.file;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;
import org.usc.utils.UploadConfigurationRead;
public class DownloadAction extends ActionSupport
{
private static final long serialVersionUID = 6329383258366253255L;
private String fileName;
private String fileRealName;
public void setFileName()
{
// 得到請求下載的文件名
String fname = ServletActionContext.getRequest().getParameter("name");
String frealname = ServletActionContext.getRequest().getParameter("realname");
try
{
/*
* 對fname參數進行UTF-8解碼,注意:實際進行UTF-8解碼時會使用本地編碼,本機爲GBK。
* 這裏使用request.setCharacterEncoding解碼無效.
* 只有解碼了getDownloadFile()方法才能在下載目錄下正確找到請求的文件
*/
fname = new String(fname.getBytes("ISO-8859-1"), "UTF-8");
frealname= new String(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文件中的: <param
* name="contentDisposition">attachment;filename="${fileName}"</param>
* 這個屬性設置的是下載工具下載文件時顯示的文件名, 要想正確的顯示中文文件名,我們需要對fileName再次編碼
* 否則中文名文件將出現亂碼,或無法下載的情況
*/
public String getFileName() throws UnsupportedEncodingException
{
fileRealName = new String(fileRealName.getBytes(), "ISO-8859-1");
return fileRealName;
}
/*
* @getDownloadFile 此方法對應的是struts.xml文件中的: <param
* name="inputName">downloadFile</param> 返回下載文件的流,可以參看struts2的源碼
*/
public InputStream getDownloadFile()
{
this.setFileName();
return ServletActionContext.getServletContext().getResourceAsStream("/"+UploadConfigurationRead.getInstance().getConfigItem("uploadFilePath").trim()+"/" + fileName);
}
@Override
public String execute() throws Exception
{
return SUCCESS;
}
}
UploadConfigurationRead
動態讀取配置文件,借鑑網上的代碼
package org.usc.utils;
import java.io.File;
import java.io.FileInputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Properties;
/**
* 動態讀取配置文件類
*
* @author MZ
*
* @Time 2009-11-24下午08:25:22
*/
public class UploadConfigurationRead {
/**
* 屬性文件全名,需要的時候請重新配置PFILE
*/
private static String PFILE = "upload.properties";
/**
* 配置文件路徑
*/
private URI uri = null;
/**
* 屬性文件所對應的屬性對象變量
*/
private long m_lastModifiedTime = 0;
/**
* 對應於屬性文件的文件對象變量
*/
private File m_file = null;
/**
* 屬性文件所對應的屬性對象變量
*/
private Properties m_props = null;
/**
* 唯一實例
*/
private static UploadConfigurationRead m_instance = new UploadConfigurationRead();
/**
* 私有構造函數
*
* @throws URISyntaxException
*/
private UploadConfigurationRead() {
try {
m_lastModifiedTime = getFile().lastModified();
if (m_lastModifiedTime == 0) {
System.err.println(PFILE + "file does not exist!");
}
m_props = new Properties();
m_props.load(new FileInputStream(getFile()));
} catch (URISyntaxException e) {
System.err.println(PFILE+"文件路徑不正確");
e.printStackTrace();
} catch (Exception e) {
System.err.println(PFILE+"文件讀取異常");
e.printStackTrace();
}
}
/**
* 查找ClassPath路徑獲取文件
*
* @return File對象
* @throws URISyntaxException
*/
private File getFile() throws URISyntaxException {
URI fileUri = this.getClass().getClassLoader().getResource(PFILE).toURI();
m_file = new File(fileUri);
return m_file;
}
/**
* 靜態工廠方法
*
* @return 返回ConfigurationRead的單一實例
*/
public synchronized static UploadConfigurationRead getInstance() {
return m_instance;
}
/**
* 讀取一特定的屬性項
*/
public String getConfigItem(String name, String defaultVal) {
long newTime = 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!!");
}
return defaultVal;
} else if (newTime > m_lastModifiedTime) {
m_props.clear();
try {
m_props.load(new FileInputStream(getFile()));
} catch (Exception e) {
System.err.println("文件重新讀取異常");
e.printStackTrace();
}
}
m_lastModifiedTime = newTime;
String val = m_props.getProperty(name);
if (val == null) {
return defaultVal;
} else {
return val;
}
}
/**
* 讀取一特定的屬性項
*
* @param name
* 屬性項的項名
* @return 屬性項的值(如此項存在), 空(如此項不存在)
*/
public String getConfigItem(String name) {
return getConfigItem(name, "");
}
}

工程結果截圖


在IE(遨遊)中多文件上傳


在Firefox中多文件上傳


在Firefox中多文件下載


在Chrome中多文件上傳


在Chrome中多文件下載


服務器中所有文件


提供原代碼下載
FileUpLoadAndDownLoad
http://usc.googlecode.com/files/FileUpLoadAndDownLoad.rar
如果有什麼建議或意見可以通過Q:506817493 或 E:[email protected],大家一起交流。
發佈了37 篇原創文章 · 獲贊 4 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章