2013-04-12 27 views
4

我有一個jsp/servlet web應用程序,客戶端可以通過下拉框選擇「課程」和「分配」,以及然後單擊按鈕以下載該課程/作業組合下列出的數據庫中的所有文件。由於壓縮文件並未作爲附件發送給瀏覽器,因此servlet代碼並不工作。我確實有一段時間下載一個文件的工作代碼,但是有些文件壓縮了這些代碼。數據庫中的所有文件本身都是zip文件,所以我試圖壓縮一大堆zip文件。我不認爲這會要求以不同於壓縮任何其他格式的文件的方式對待它們。任何人都可以看到缺少什麼?這是我處理下載的servlet中的doGet方法代碼。大部分代碼都是在stackoverflow上找到的。請注意,FileSubmitted對象包含所有用於數據庫中的每個文件的文件信息,包括斑點本身我DOA:使用servlet,如何從數據庫下載多個文件並將其壓縮爲客戶端下載

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
{ 
    List<FileSubmitted> fileList = new ArrayList<FileSubmitted>(); 
    String course= request.getParameter("course"); 
    String assignment = request.getParameter("assignment"); 

    java.sql.PreparedStatement pstmt = null; 
    java.sql.Connection conn = null; 
    ResultSet rs; 
    String queryString; 

    try { 
     conn = ConnectionManager.getConnection(); 
     conn.setAutoCommit(false); 

     queryString = "SELECT * FROM files WHERE courseID=\""+course+"\" AND assignmentID=\""+assignment+"\";"; 
     pstmt = conn.prepareStatement(queryString); 
     rs = pstmt.executeQuery(queryString); 
     while(rs.next()) 
     { 
      fileList.add(new FileSubmitted(rs.getString("username"), 
              rs.getString("courseID"), 
              rs.getString("assignmentID"), 
              rs.getString("fileName"), 
              rs.getString("mimeType"), 
              (Blob) rs.getBlob("contents"))); 
     } 


     response.setContentType("application/zip"); 
     response.setHeader("Content-Disposition", "attachment; filename=\"allfiles.zip\""); 

     ZipOutputStream output = null; 
     byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; 

     try { 
      output = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE)); 

      for (FileSubmitted file : fileList) 
      { 
       InputStream input = null; 
       try { 
         input = new BufferedInputStream(file.getContents().getBinaryStream(), DEFAULT_BUFFER_SIZE); 
         output.putNextEntry(new ZipEntry(file.getFileName())); 
         for (int length = 0; (length = input.read(buffer)) > 0;) 
         { 
          output.write(buffer, 0, length); 
         } 
        }//try 
        catch (SQLException e) {e.printStackTrace();} 
        finally{} 
        output.closeEntry(); 
      }//for 
      }//try 
      finally{} 
    } 
    catch (Exception e1) {e1.printStackTrace();} 
    finally{} 
} 
+1

請你可以擴展'某些東西正在被這個代碼壓縮文件卡住' - 是否有錯誤,你有沒有添加日誌記錄來看看發生了什麼?您可以嘗試通過從一個servlet中取出郵政編碼並使用少量已知文件的主方法運行來隔離問題。嘗試使用命令行壓縮相同的文件,看看時間是什麼 - 也許你的文件很大,而且只需要很長時間。 – Romski

+0

對不起,我意識到這是模糊的。通過「有些東西卡住了」,我的意思是我沒有收到任何錯誤,但是zip文件沒有被髮送到瀏覽器進行下載。我曾嘗試在整個代碼中使用print語句來確保整個方法正在執行,而且似乎是這樣。這只是不完成我想要的。我會嘗試一些你的建議。謝謝。 – Lani1234

回答

4

在這種情況下,可以幫助別人,我找到了答案的問題。上述代碼實際上可以完美地用於從數據庫下載多個文件並創建一個供客戶端下載的zip文件。問題是我通過ajax調用servlet,顯然你不能通過ajax調用下載文件。所以我改變了我的jsp頁面,通過提交表單來調用servlet,然後完美地下載到瀏覽器。

1

首先創建一個包含所有zip文件的zip文件。

使用ServletOutputStream,而不是ZipOutputStream

然後使用下面的代碼

protected void doGet(final HttpServletRequest request, final HttpServletResponse response) { 
     final String filename = "/usr/local/FileName" + ".zip"; 

     BufferedInputStream buf = null; 
     ServletOutputStream myOut = null; 

     try { 
      myOut = response.getOutputStream(); 

      File myfile = new File(filename); 

      if (myfile.exists()) { 
       //myfile.createNewFile(); 
       //set response headers 
       response.setHeader("Cache-Control", "max-age=60"); 
       response.setHeader("Cache-Control", "must-revalidate"); 
       response.setContentType("application/zip"); 

       response.addHeader("Content-Disposition", "attachment; filename=" + filename); 

       response.setContentLength((int) myfile.length()); 

       FileInputStream input = new FileInputStream(myfile); 
       buf = new BufferedInputStream(input); 
       int readBytes = 0; 

       //read from the file; write to the ServletOutputStream 
       while ((readBytes = buf.read()) != -1) { 
        myOut.write(readBytes); 
       } 
      } 

     } catch (Exception exp) { 
     } finally { 
      //close the input/output streams 
      if (myOut != null) { 
       try { 
        myOut.close(); 
       } catch (IOException ex) { 
       } 
      } 
      if (buf != null) { 
       try { 
        buf.close(); 
       } catch (IOException ex) { 
       } 
      } 

     } 
    } 
+0

謝謝,我會試試這個Kiran Jujare。你能告訴我 - '最終的字符串文件名=「/ usr/local/FileName」+「.zip」;'是已經創建的zip文件的名稱?你怎麼知道擴展是'/ usr/local/FileName'? – Lani1234

+0

您必須創建您想要下載傳遞名稱到'String filename'的zip文件。 –

相關問題