struts2 多文件下载

时间:2022-10-21 15:52:10

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