2013-04-12 1 views
4

클라이언트가 드롭 다운 상자를 통해 "코스"및 "배정"을 선택할 수있는 jsp/servlet 웹 앱이 있고 버튼을 클릭하면 해당 코스/할당 조합 아래에 나열된 데이터베이스의 모든 파일을 다운로드 할 수 있습니다. zip 파일이 브라우저에 첨부 파일로 전송되지 않으므로 서블릿 코드가 제대로 작동하지 않습니다. 한 번에 하나의 파일을 다운로드하기위한 작업 코드가 있지만 파일을 압축하는 데이 코드가 얽혀 있습니다. 데이터베이스의 모든 파일은 실제로 zip 파일 자체이므로 여러 개의 zip 파일을 압축하려고합니다. 필자는 다른 형식의 파일을 압축하는 것과 다르게 취급해야한다고 생각하지 않았습니다. 아무도 빠진 것을 볼 수 있습니까? 다음은 다운로드를 처리하는 서블릿의 doGet 메소드 코드입니다. 이 코드의 대부분은 stackoverflow에서 발견되었습니다.서블릿을 사용하여 데이터베이스에서 여러 파일을 다운로드하고 클라이언트 다운로드 용으로 압축하는 방법

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

'파일을 압축하는 데이 코드가 사용되지 않습니다'라는 확장 기능을 사용하십시오. 오류가 있습니까? 로깅을 추가하여 진행 상황을 확인 했습니까? 서블릿에서 zip 코드를 가져 와서 소수의 알려진 파일을 사용하여 main 메소드에서 실행하여 문제를 격리 할 수 ​​있습니다. 명령 줄을 사용하여 동일한 파일을 압축하여 시간을 확인하십시오. 아마도 파일이 크고 시간이 오래 걸릴 수도 있습니다. – Romski

+0

미안하지만, 그것이 막연하다는 것을 알았습니다. "무언가가 고생하고있다"는 말은 오류가 발생하지 않았지만 zip 파일이 브라우저로 다운로드되지 않고 있다는 뜻입니다. 필자는 전체 메서드가 실행되고 있는지 확인하기 위해 코드 전체에 print 문을 두어 보았습니다. 그것은 단지 내가 원하는 것을 성취하지 못합니다. 나는 당신의 제안을 시도 할 것이다. 고맙습니다. – Lani1234

답변

4

를 사용, 그 문제에 대한 답을 발견했다. 위에 게시 된 코드는 실제로 데이터베이스에서 여러 파일을 다운로드하고 클라이언트가 다운로드 할 zip 파일을 만들 때 완벽하게 작동합니다. 문제는 내가 아약스를 통해 서블릿을 호출하고 있었고 분명히 아약스 호출을 통해 파일을 다운로드 할 수 없다는 것이 었습니다. 그래서 jsp 페이지를 변경하여 양식을 제출하여 서블릿을 호출하면 다운로드가 브라우저로 완벽하게 전달됩니다.

1

먼저 모든 zip 파일이 포함 된 zip 파일을 만들기 : FileSubmitted 객체가 물방울 자체를 포함하여 데이터베이스의 각 파일에 대한 모든 파일 정보를 포함하는 내 DOA 있음을 유의하시기 바랍니다.

사용 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

감사합니다. 나는이 키란 주야르를 시험해 보겠습니다. 'final String filename = "/ usr/local/FileName"+ ".zip";' 이미 생성 된 zip 파일의 이름입니까? 확장이 '/ usr/local/FileName'인지 어떻게 알 수 있습니까? – Lani1234

+0

당신은'String filename'에 이름을 넘겨 줄 다운로드 파일을 만들어야합니다. –