天天看點

servlet實作多檔案打包下載下傳

當使用者一次下載下傳多個檔案時。普通情況是,每下載下傳一個檔案,均要彈出一個下載下傳的對話框。這給使用者造成了非常大不便。

比較理想的情況是,使用者選擇多個檔案後。server後端直接将多個檔案打包為zip。以下貼出實作代碼。

前端Javascript代碼(使用Javascript建立表單。通過送出表單的方式訪問後端的MultiDownload):

var tmpForm = document.createElement("form");
tmpForm.id = "form1" ; 
tmpForm.name = "form1" ;                     
document.body.appendChild(tmpForm);

var tmpInput = document.createElement("input"); 
// 設定input對應參數 
tmpInput.type = "text"; 
tmpInput.name = "fileUrls" ; 
tmpInput.value = downloadUrls;
// 将該輸入框插入到 tmpform 中
tmpForm.appendChild(tmpInput);

tmpForm.action= "servlet/MultiDownload" ;
tmpForm.method= "get";                     
tmpForm.submit();
      
//從html從移除該form
document.body.removeChild(tmpForm);
      

後端MultiDownload代碼:

public class MultiDownload extends HttpServlet {
  private static final long serialVersionUID = 1L;

  /**
   * @see HttpServlet#HttpServlet()
   */
  public MultiDownload() {
    super();
    // TODO Auto-generated constructor stub
  }

  /**
   * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
   *      response)
   */
  protected void doGet(HttpServletRequest request,
      HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    String strArray = null;
    strArray = request.getParameter("fileUrls");
    //傳遞到servlet時,預設将編碼轉換為ISO-8859-1,将其又一次轉碼為GBK
    strArray=new String(strArray.getBytes("ISO-8859-1"), "GBK"); 
    String[] filePathArray = strArray.split(",");
    String zipFileName = "product.zip";
    response.setContentType("application/x-msdownload" ); // 通知客戶檔案的MIME類型:
    response.setHeader("Content-disposition" , "attachment;filename=" + zipFileName);
    //要下載下傳的檔案檔案夾
    ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
    for (String filePath : filePathArray) {
      File file = new File(filePath);
      doZip(file, zos);
    }     
    zos.close();
  }
  /**
   *  打包為 zip 檔案
   * @param file 待打包的檔案
   * @param zos zip zip輸出流
   * @throws IOException 
   */
  private void doZip(File file, ZipOutputStream zos)
      throws IOException {
    if(file.exists()) {
      if (file.isFile()) {
        //假設是檔案,寫入到 zip 流中
        zos.putNextEntry(new ZipEntry(file.getName()));
        FileInputStream fis = new FileInputStream(file);
        byte[] buffer = new byte[1024];
        int r = 0;
        while ((r = fis.read(buffer)) != -1) {
          zos.write(buffer, 0, r);
        }
        zos.flush();        
        fis.close();
      } else {
        //假設是檔案夾。遞歸查找裡面的檔案
        String dirName = file.getName() + "/";
        zos.putNextEntry(new ZipEntry(dirName));
        File[] subs = file.listFiles();
        for (File f : subs) {
          makeZip(f, dirName, zos);
        }
      }
    }
  }
  /**
   * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
   *      response)
   */
  protected void doPost(HttpServletRequest request,
      HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
  }

}
      

繼續閱讀