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;
} }