Step1:导入支持jar包
commons-fileupload-1.3.1.jar
commons-io-2.4.jar
jstl-1.2.jar
standard-1.1.2.jar
commons-compress-1.10.jar 文件压缩工具包
Step2:编写请求下载jsp
<script type="text/javascript" src="jquery-1.8.3.js"></script> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <h1>文件列表--多文件</h1> <div> <ul> <c:forEach items="${filenames }" var="filename"> <li> <input type="checkbox" value="${filename }" name="filename" class="chkli chk"> <img alt="加载中..." src="/imgs/${filename }" width="100"> <a href="upload_download/download_file.action?filename=${filename }">download</a> </li> </c:forEach> <li> <input type="checkbox" name="" value="" class="chkall chk">全选 <a href="upload_download/download_multi_file.action?params=''" class="download_all">download all</a> </li> </ul> </div> <script type="text/javascript"> $(function(){ $(".chk").on("click",function(){ var params = "" ; var chklis = $(".chkli"); for (var i = 0; i < chklis.length; i++) { if($(chklis[i]).attr("checked")){ params += $(chklis[i]).val() + "," } } var href_path = $(".download_all").attr("href"); var href_path_params = href_path.split("=")[0] +"="+ params ; var href_path_params = href_path_params.substring(0,href_path_params.length-1); $(".download_all").attr("href",href_path_params); }); }); </script>
Step3:编写action
package com.struts2.fileuplad.action; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.text.SimpleDateFormat; import javax.servlet.http.HttpServletRequest; import com.struts2.util.BaseAware; import com.struts2.util.ZipFileUtil; public class MultipartFileDownloadAction extends BaseAware { private static final long serialVersionUID = -8551022600136584709L; //前台传递过来多个文件拼接的字符串 private String params ; public String getParams() { return params; } public void setParams(String params) { this.params = params; } private String filename; public String getFilename() { return filename ; } public void setFilename(String filename) throws UnsupportedEncodingException { this.filename = filename; } @Override public String execute() { return SUCCESS; } //该方法被对应的请求action中result的参数调用 //即:<param name="contentDisposition">attachment;fileName="${downloadFileName}"</param> public String getDownloadFileName() throws UnsupportedEncodingException{ //使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。 // 构造一个新的 String,运用指定的字符集解码指定的字节数组。 //这里本该设置为UTF-8 但是IE依然显示乱码 换成GBK之后基本可以全部兼容了,有问题可以再修改 return this.filename = new String(filename.getBytes("GBK"),"ISO-8859-1"); } private HttpServletRequest request; public void setServletRequest(HttpServletRequest request) { this.request = request; } //该方法被对应的请求action中result的参数调用 //即:<param name="inputName">inputStream</param> public InputStream getInputStream() throws FileNotFoundException, UnsupportedEncodingException { filename = request.getServletContext().getInitParameter("struts2_upload_imgs_path") +File.separator + "struts2-多个文件下载-" + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(System.currentTimeMillis()) + ".zip" ; /** * 注意:::这个功能点应该添加一个拦截器 处理params为null或者""问题 */ if(params != null && !"".equals(params)) { //将多个附件的路径取出 String[] attachmentPathArray = params.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( request.getServletContext().getInitParameter("struts2_upload_imgs_path") +File.separator +attachmentPathArray[i].trim()); if(file.exists()) { files[i] = file; } } } System.out.println("getDownloadFileName-----"+filename); //将多个附件压缩成zip ZipFileUtil.compressFiles2Zip(files,filename); } } File file = new File(filename); FileInputStream fis = new FileInputStream(file); return fis; } }
Step4:配置struts.xml
<action name="download_multi_file" class="com.struts2.fileuplad.action.MultipartFileDownloadAction"> <result type="stream"> <param name="contentType">application/octet-stream</param> <param name="contentDisposition">attachment;fileName="${downloadFileName}"</param> <param name="inputName">inputStream</param> <param name="bufferSize">1024</param> </result> </action>
Step5:处理文件压缩工具类
package com.struts2.util; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.zip.Zip64Mode; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream; import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; /** * Zip文件工具类 */ public class ZipFileUtil { /** * 把文件压缩成zip格式 * @param files 需要压缩的文件 * @param zipFilePath 压缩后的zip文件路径 ,如"D:/test/aa.zip"; */ public static void compressFiles2Zip(File[] files,String zipFilePath) { if(files != null && files.length >0) { if(isEndsWithZip(zipFilePath)) { ZipArchiveOutputStream zaos = null; try { File zipFile = new File(zipFilePath); zaos = new ZipArchiveOutputStream(zipFile); //Use Zip64 extensions for all entries where they are required zaos.setUseZip64(Zip64Mode.AsNeeded); //将每个文件用ZipArchiveEntry封装 //再用ZipArchiveOutputStream写到压缩文件中 for(File file : files) { if(file != null) { ZipArchiveEntry zipArchiveEntry = new ZipArchiveEntry(file,file.getName()); zaos.putArchiveEntry(zipArchiveEntry); InputStream is = null; try { is = new BufferedInputStream(new FileInputStream(file)); byte[] buffer = new byte[1024 * 5]; int len = -1; while((len = is.read(buffer)) != -1) { //把缓冲区的字节写入到ZipArchiveEntry zaos.write(buffer, 0, len); } //Writes all necessary data for this entry. zaos.closeArchiveEntry(); }catch(Exception e) { throw new RuntimeException(e); }finally { if(is != null) is.close(); } } } zaos.finish(); }catch(Exception e){ throw new RuntimeException(e); }finally { try { if(zaos != null) { zaos.close(); } } catch (IOException e) { throw new RuntimeException(e); } } } } } /** * 把zip文件解压到指定的文件夹 * @param zipFilePath zip文件路径, 如 "D:/test/aa.zip" * @param saveFileDir 解压后的文件存放路径, 如"D:/test/" */ public static void decompressZip(String zipFilePath,String saveFileDir) { if(isEndsWithZip(zipFilePath)) { File file = new File(zipFilePath); if(file.exists()) { InputStream is = null; //can read Zip archives ZipArchiveInputStream zais = null; try { is = new FileInputStream(file); zais = new ZipArchiveInputStream(is); ArchiveEntry archiveEntry = null; //把zip包中的每个文件读取出来 //然后把文件写到指定的文件夹 while((archiveEntry = zais.getNextEntry()) != null) { //获取文件名 String entryFileName = archiveEntry.getName(); //构造解压出来的文件存放路径 String entryFilePath = saveFileDir + entryFileName; byte[] content = new byte[(int) archiveEntry.getSize()]; zais.read(content); OutputStream os = null; try { //把解压出来的文件写到指定路径 File entryFile = new File(entryFilePath); os = new BufferedOutputStream(new FileOutputStream(entryFile)); os.write(content); }catch(IOException e) { throw new IOException(e); }finally { if(os != null) { os.flush(); os.close(); } } } }catch(Exception e) { throw new RuntimeException(e); }finally { try { if(zais != null) { zais.close(); } if(is != null) { is.close(); } } catch (IOException e) { throw new RuntimeException(e); } } } } } /** * 判断文件名是否以.zip为后缀 * @param fileName 需要判断的文件名 * @return 是zip文件返回true,否则返回false */ public static boolean isEndsWithZip(String fileName) { boolean flag = false; if(fileName != null && !"".equals(fileName.trim())) { if(fileName.endsWith(".ZIP")||fileName.endsWith(".zip")){ flag = true; } } return flag; } }