首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> JSP 程式設計 >> 關於JSP

JSP 實現檔案下載四種方案完整對比與最佳實踐

     編輯:關於JSP

檔案下載本質是「伺服器將檔案轉為輸出流 → 瀏覽器接收流 → 提示另存」。根據業務需求(權限控制、大檔支援、斷點續傳),可選擇四種方案。

方案一:直接連結(最簡單)

<a href="/files/report.pdf">下載報表</a>
  • 優點:零代碼、CDN 友好、瀏覽器原生支援斷點續傳、多執行緒下載。
  • 缺點:檔案路徑暴露、無權限控制、無法統計下載次數、無法動態生成內容。

方案二:Servlet/JSP 流式輸出(最通用)

<%@ page import="java.io.*" %>
<%
  String filepath = "E:/data/report.pdf";
  File file = new File(filepath);
  String filename = URLEncoder.encode(file.getName(), "UTF-8");

  response.setContentType("application/octet-stream");
  response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
  response.setContentLengthLong(file.length());

  try (InputStream in = new FileInputStream(file);
       OutputStream out = response.getOutputStream()) {
    byte[] buf = new byte[8192];
    int len;
    while ((len = in.read(buf)) > 0) out.write(buf, 0, len);
  }
%>
  • 關鍵 Header:Content-Disposition: attachment 強制下載;Content-Length 支援進度條。
  • 大檔建議:response.setBufferSize(0) 關閉緩衝,避免 OOM。
  • 權限控制:在輸出前檢查 Session/DB 權限。

方案三:Applet 客戶端下載(已淘汰)

  • Servlet 輸出流 → 簽名 Applet 接收 → 本地寫檔 → 可顯示進度條、支援斷點續傳。
  • 缺點:需用戶信任簽名、JRE 環境、瀏覽器現已全面封殺 NPAPI/Applet。

方案四:現代最佳實踐——Spring MVC / Servlet 3.0 + NIO

@GetMapping("/download/{id}")
public ResponseEntity<Resource> download(@PathVariable Long id, HttpServletRequest req) {
  File file = storageService.getFile(id);
  return ResponseEntity.ok()
    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + encode(file.getName()) + "\"")
    .contentLength(file.length())
    .contentType(MediaType.APPLICATION_OCTET_STREAM)
    .body(new FileSystemResource(file)); // Spring 自動使用零拷貝 FileChannel
}
  • 零拷貝(FileChannel.transferTo)、自動支援 Range 請求(斷點續傳)、整合權限攔截器。
  • Nginx X-Accel-Redirect / Apache mod_xsendfile 可進一步卸載靜態檔傳輸給 Web Server。

選型建議

場景推薦方案
公開靜態資源、大檔、高併發Nginx X-Accel-Redirect / 直接連結 + CDN
需權限、動態生成、中小檔Servlet/JSP 流式輸出或 Spring MVC Resource
需斷點續傳、超大檔(>1GB)支援 Range 的 Controller + 對象存儲簽名 URL

核心原則:業務邏輯(權限/統計)走 Java,資料傳輸(IO/頻寬)交給 Web Server/對象存儲。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved