使用場景:
1)在JSP頁面,有一個展現附件的列表。
2)對列表中的每一個附件,提供單獨下載。
3)同時提供復選框,提供選擇多個文件下載。
實現思路:
1)寫一個通用的具有下載功能的Action,只需要接收一個文件路徑就可以下載。單個附件的下載直接調用這個Action,只需要傳遞附件的路徑即可。
2)多個文件下載,可以將多個文件的路徑傳遞到一個處理Action,將多個文件打包成zip。然后重定向到通用的下載Action,同時傳遞zip包的路徑給通用下載Action。
1、通用的下載Action。
這個Action里面有一個成員變量fileName,負責接收傳遞的文件路徑。
package cn.luxh.struts2.action; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; /** * 文件下載 * @author Luxh */ public class DownloadAction extends ActionSupport { private static final long serialVersionUID = -3036349171314867490L; //文件名 private String fileName; public String getFileName() { return fileName; } public void setFileName(String fileName) throws UnsupportedEncodingException { //用UTF-8重新編碼文件名,解決中文亂碼 this.fileName = new String(fileName.getBytes("ISO-8859-1"),"UTF-8"); } public InputStream getInputStream() throws UnsupportedEncodingException, FileNotFoundException{ HttpServletResponse response = ServletActionContext.getResponse(); //attachment,以附件的方式下載文件,會打開保存文件對話框;inline,以內聯的方式下載,瀏覽器會直接打開文件 response.setHeader("Content-Disposition", "attachment;fileName=" + java.net.URLEncoder.encode(fileName,"UTF-8"));//java.net.URLEncoder.encode(fileName,"UTF-8") 編碼轉換,解決亂碼 //如果fileName是相對路徑 //return ServletActionContext.getServletContext().getResourceAsStream(fileName); //如果fileName是絕對路徑 return new BufferedInputStream(new FileInputStream(fileName)); } @Override public String execute() throws Exception { return SUCCESS; } }
這個Action的配置文件:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <package name="download" namespace="/download" extends="default"> <action name="download" class="cn.luxh.struts2.action.DownloadAction"> <result name="success" type="stream"> <!-- 下載文件類型定義 --> <param name="contentType">application/octet-stream</param> <!-- 下載文件輸出流定義 --> <param name="inputName">inputStream</param>
<!-- 下載文件處理方式 -->
<param name="contentDisposition">attachment;filename="${fileName}"</param> <!-- 下載文件的緩沖大小 --> <param name="bufferSize">4096</param> </result> </action> </package> </struts>
2、處理多個附件下載的Action。
package cn.luxh.struts2.action; import java.io.File; import java.text.SimpleDateFormat; import java.util.Date; import cn.luxh.utils.ZipFileUtil; import com.opensymphony.xwork2.ActionSupport; /** * 處理多個附件下載 * @author Luxh */ public class MultiFileDownloadAction extends ActionSupport { private static final long serialVersionUID = 2743077909387361587L; //接收JSP頁面傳遞過來的附件的路徑 private String attachmentPath; //最終壓縮后的zip文件的路徑,傳遞給通用的下載Action private String fileName; /** * 下載多個附件 * 實現:將多個附近壓縮成zip包,然后再下載zip包 */ public String downloadMultiFile() { //使用當前時間生成文件名稱 String formatDate =new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()); //壓縮后的zip文件存放路徑 fileName = "D:/test/" + formatDate + ".zip"; if(attachmentPath != null && !"".equals(attachmentPath)) { //將多個附件的路徑取出 String[] attachmentPathArray = attachmentPath.split(","); if(attachmentPathArray != null && attachmentPathArray.length >0) { File[] files = new File[attachmentPathArray.length]; for(int i=0;i<attachmentPathArray.length;i++) { if(attachmentPathArray[i] != null) { File file = new File(attachmentPathArray[i].trim()); if(file.exists()) { files[i] = file; } } } //將多個附件壓縮成zip ZipFileUtil.compressFiles2Zip(files,fileName); } } return SUCCESS; } public String getAttachmentPath() { return attachmentPath; } public void setAttachmentPath(String attachmentPath) { this.attachmentPath = attachmentPath; } public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } }
Action中的壓縮文件類ZipFileUtil參考 http://www.cnblogs.com/luxh/archive/2012/06/28/2568758.html
配置文件:
<!--將多個附件壓縮后重定向到公共的下載Action下載文件 --> <action name="downloadMultiFile" class="cn.luxh.struts2.action.MultiFileDownloadAction" method="downloadMultiFile"> <result type="redirectAction"> <param name="actionName">download</param> <param name="nameSpace">/download</param> <!--附件的完整路徑 --> <param name="fileName">${fileName}</param> </result> </action>
3、附件列表展現的JSP頁面。
<%@ page contentType="text/html;charset=UTF-8" language="java"%> <%@ taglib prefix="s" uri="/struts-tags"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html> <html> <head> <title>File Download</title> <meta http-equiv="description" content="error"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <!--<link rel="stylesheet" type="text/css" href="./styles.css">--> <script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-1.7.2.min.js"></script> <script type="text/javascript"> function checkFile() { if($("#all").attr("checked")){ $("input[name='attachmentPath']").attr("checked",true); }else { $("input[name='attachmentPath']").attr("checked",false); } } </script> </head> <body> <form action="${pageContext.request.contextPath}/index/downloadMultiFile" method="post"> <table> <tr> <th> <input type="checkbox" name="all" id="all" onchange="checkFile()">全選 </th> <th> 文件名 </th> <th> 文件路徑 </th> <th> 下載 </th> </tr> <c:forEach items="${attachmentList}" var="attachment"> <tr> <td> <input type="checkbox" name="attachmentPath" value="${attachment.filePath}"> </td> <td>${attachment.fileName}</td> <td>${attachment.filePath}</td> <td> <a href="${pageContext.request.contextPath}/download/download?fileName=${attachment.filePath}">下載</a> </td> </tr> </c:forEach> </table> <tr> <td> <input type="submit" value="下載所選文件" id="submit"> </td> </tr> </form> </body> </html>