使用场景:
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;
- }
- }
- <?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="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" οnchange="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>