2015-09-14 49 views
3

我正在研究一個Web應用程序(Java/JSP),並且它的一部分是允許用戶只下載一次「請求」文件。當他們點擊「下載」按鈕時,他們將被要求保存/打開或取消該文件,並且他們響應文件的任何內容都將被標記爲已下載,並且用戶將無法再次下載。 我試圖找出一種方法,當用戶用「取消」進行響應時檢查下載文件的數量,並檢查用戶是否確實完全下載了該文件。在Java中檢測並報告完成的下載文件

這裏是Java部分:

@WebServlet("/download") 
    public class download extends HttpServlet { 
    private static final long serialVersionUID = 1L; 
    private static final int DEFAULT_BUFFER_SIZE = 10240; 
/** 
* @see HttpServlet#HttpServlet() 
*/ 
public download() { 
    super(); 
    // TODO Auto-generated constructor stub 
} 

/** 
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse 
*  response) 
*/ 
protected void doGet(HttpServletRequest request, HttpServletResponse response) 
     throws ServletException, IOException { 
    try { 

     Class.forName("org.sqlite.JDBC"); 
     Connection c = DriverManager.getConnection("jdbc:sqlite:C:\\sqlite\\mascapp.db"); 
     c.setAutoCommit(false); 
     Cookie[] cookies = request.getCookies(); 
     if(request.getSession().getAttribute("aeid") == null || request.getSession().getAttribute("uid") == null) 
     { 
      response.sendRedirect("/index.jsp"); 
     } 
     int ae_num = Integer.parseInt(request.getSession().getAttribute("aeid").toString()); 




     String sql = "SELECT file, filename FROM reports INNER JOIN download USING(tipid) WHERE reports.tipid = ?"+ 
       "AND download.ts_" + ae_num+ " = 0;"; 

     PreparedStatement stmt = c.prepareStatement(sql); 
     String tipNum = request.getParameter("tipid"); 
     if (tipNum != null) { 

      stmt.setString(1, tipNum); 
      //stmt.setString(2, tipNum); 
      ResultSet res = stmt.executeQuery(); 
      BufferedInputStream fileBlob = null; 
      String filename = ""; 

      while (res.next()) { 
       fileBlob = new BufferedInputStream(res.getBinaryStream("file"), DEFAULT_BUFFER_SIZE); 

       filename = res.getString("filename"); 
      } 
      if (fileBlob != null) { 
       System.out.println(filename); 
       response.setContentType("APPLICATION/OCTET-STREAM"); 
       response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\""); 

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

       byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; 
       int length; 
       while ((length = fileBlob.read(buffer)) > 0) { 
        output.write(buffer, 0, length); 
       } 

       output.close(); 
       fileBlob.close(); 
       Date now = new Date(); 

       sql = "UPDATE download SET ts_" + ae_num + " = " + now.getTime() + " WHERE tipid = ?;"; 
       System.out.println(sql); 
       stmt = c.prepareStatement(sql); 
       stmt.setString(1, tipNum); 

       stmt.executeUpdate(); 
       stmt.close(); 

       c.commit(); 
       c.close(); 
      } 
      else 
      { 

       c.close(); 
       response.sendRedirect("/MASC/formdownloaded.jsp"); 

      } 
     } 
     else 
     { 
      response.getWriter().append("<html><body><h1>Error: no param</h1></body></html>"); 
      c.close(); 

     } 
    } catch (SQLException | ClassNotFoundException e) { 
     e.printStackTrace(); 

    } 
} 

/** 
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse 
*  response) 
*/ 
protected void doPost(HttpServletRequest request, HttpServletResponse response) 
     throws ServletException, IOException { 
    // TODO Auto-generated method stub 
    doGet(request, response); 
} 

} 

任何解決方案或建議?先謝謝你。

+0

我覺得你更好的選擇是嘗試檢測和報告成功下載,並使用這些報告來告知w ^用戶是否已經下載了該文件。否則,如果用戶的下載中斷?但是,我擔心如何實現這一點,我沒有具體的建議。無論如何,試圖在你的用戶上強制任何東西都是一個糟糕的計劃。這是不可能被讚賞的。 –

+0

我已經更新了這個問題,我同意你的意見。 我如何跟蹤用戶按「取消」或「下載」? – user4071915

+0

您可以強制下載: http://stackoverflow.com/questions/11353425/force-a-browser-to-save-file-as-after-clicking-link –

回答

1

查看本頁面:http://johnculviner.com/jquery-file-download-plugin-for-ajax-like-feature-rich-file-downloads/(此鏈接有時不起作用,如果您遇到問題,請點擊這裏鏈接到github:https://github.com/johnculviner/jquery.fileDownload)。

看起來你可以在這裏做的最好的事情是確保下載是通過檢查客戶端的特殊cookie從服務器下載文件流發回來開始的。對於你要的Cookie在這個線程加入到servlet響應,如: Set cookie only after file download complete.

所以,在你的servlet doGet方法的最後,你應該有一些這樣的:

Cookie fileDwnld = new Cookie("fileDownload", "true"); 
fileDwnld.setPath("/"); 
response.addCookie(fileDwnld); 

這裏是客戶端代碼:

<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script> 
<script src="jquery.fileDownload.js"></script> 
<script> 
$(document).ready(function() { 
    $("#btnSubmit").click(function(){ 
     $.fileDownload('path/to/servlet') 
      .done(function() { alert('File download a success!'); }) 
      .fail(function() { alert('File download failed!'); }); 
    }); 
}); 

-5

我沒有一個正確的答案,但我知道「附件」在標題中強制瀏覽器「下載」該文件,相比之下「打開它」,如果你明白我的意思。嘗試刪除該標題,看看你是否得到所需的效果。

1

答案是不這樣做。那些對話是有原因的,其中一些涉及安全。

你想要做什麼取決於爲什麼你只希望用戶下載文件一次。由於各種原因,下載可能會失敗,所以如果用戶在下載過程中丟失了連接,你會怎麼做?

+0

這是我的問題的一部分,我怎麼能一般跟蹤從Web應用程序中使用JAVA數據庫(Sqlite)下載的文件,以知道用戶是否真的完全下載文件? – user4071915