在 Web 應用開發中,提供文件下載功能是常見需求。本文針對基於 Spring、Struts2、iBatis 框架的專案,探討在主介面增加下載鏈接的兩種實現思路,並分析其優缺點。
最簡單的方式是在頁面上直接給出文件在服務器上的真實路徑(或相對 Web 根目錄的 URL),例如:
<a href="/files/report.pdf">下載報表</a>
優點:實現極其簡單,無需額外編寫後端代碼,瀏覽器直接請求靜態資源,效率高。
缺點:文件存儲路徑對外可見,存在安全風險;難以實現下載權限控制、統計、斷點續傳等進階功能。
在 Action/Controller 中通過輸出流將文件內容寫入 HttpServletResponse,關鍵步驟如下:
Content-Disposition: attachment; filename="xxx.pdf" 強制瀏覽器彈出下載對話框。Content-Type 為 application/octet-stream 或具體 MIME 類型。FileInputStream 或 BufferedInputStream 讀取文件,寫入 ServletOutputStream。flush()。示例代碼片段:
public void download(HttpServletResponse response) throws IOException {
File file = new File("/data/files/report.pdf");
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=report.pdf");
try (FileInputStream fis = new FileInputStream(file);
ServletOutputStream out = response.getOutputStream()) {
byte[] buffer = new byte[4096];
int len;
while ((len = fis.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
out.flush();
}
}
優點:完全隱藏服務器文件結構,可在輸出前進行權限校驗、記錄下載日誌、限速等。
缺點:佔用服務器內存與 CPU,大文件下載時需注意流控制,避免 OOM。
Resource 抽象或 Struts2 的 StreamResult 簡化代碼。