public void download(HttpServletRequest request, HttpServletResponse response) throws IOException {
String filePath = request.getSession().getServletContext().getRealPath("/apk/android/NCB.apk");
File file = new File(filePath);
if (!file.exists()) return;
String fileName = URLEncoder.encode(file.getName(), "UTF-8");
response.reset();
response.setContentType(request.getServletContext().getMimeType(fileName));
response.addHeader("Content-Disposition", "attachment; filename=" + fileName);
response.setContentLength((int) file.length());
try (InputStream in = new FileInputStream(file);
ServletOutputStream out = response.getOutputStream()) {
byte[] buf = new byte[4096];
int len;
while ((len = in.read(buf)) != -1) {
out.write(buf, 0, len);
}
}
}
public void downloadTemplate(HttpServletRequest request, HttpServletResponse response) {
String path = request.getSession().getServletContext().getRealPath("");
File file = new File(path + "\\file\\template\\模板文件.xls");
String userAgent = request.getHeader("User-Agent");
byte[] bytes = userAgent.contains("MSIE") ? file.getName().getBytes() : file.getName().getBytes("UTF-8");
String fileName = new String(bytes, "ISO-8859-1");
response.setContentType("multipart/form-data");
response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName, "UTF-8"));
try (InputStream in = new FileInputStream(file)) {
IOUtils.copy(in, response.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
| 維度 | 原生 Servlet | Spring MVC + IOUtils |
|---|---|---|
| 代碼量 | 手動管理流、緩衝區、異常 | IOUtils.copy/closeQuietly 一行搞定 |
| 中文文件名 | URLEncoder.encode | User-Agent 區分 IE/非 IE 編碼策略 + ISO-8859-1 轉碼 |
| 資源釋放 | finally 手動關閉 | Try-with-resources / closeQuietly |
| 適用場景 | 無 Spring 環境、需精細控制 | Spring 項目、追求簡潔健壯 |
Content-Disposition: attachment; filename=... 強制瀏覽器下載而非預覽。Content-Length 支援下載進度條。BufferedInputStream/OutputStream 或 NIO FileChannel.transferTo 零拷貝。Range)支援斷點續傳。Spring MVC 專案首選 IOUtils.copy 方案,代碼少、異常安全、中文文件名兼容性好;非 Spring 環境參考原生寫法並補全資源釋放邏輯。