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

Java Web 文件下載與中文亂碼完美解決方案

     編輯:Java 相關知識

下載流程五步法

  1. 定位文件絕對路徑
  2. 獲取輸入流 FileInputStream
  3. 獲取響應輸出流 response.getOutputStream()
  4. 緩衝複製 IOUtils.copy 或手寫循環
  5. 關閉流、設置響應頭

核心工具類

public class DownloadUtils {
    public static void download(HttpServletRequest req, HttpServletResponse resp,
                                String filePath, String fileName) throws IOException {
        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath));
             BufferedOutputStream bos = new BufferedOutputStream(resp.getOutputStream())) {

            long len = new File(filePath).length();
            resp.setCharacterEncoding("UTF-8");
            resp.setContentType("multipart/form-data");
            resp.setHeader("Content-Length", String.valueOf(len));

            // 核心:多瀏覽器中文文件名編碼
            String ua = req.getHeader("User-Agent");
            byte[] nameBytes = ua.contains("MSIE") || ua.contains("Trident")
                    ? fileName.getBytes()                    // IE/Edge
                    : fileName.getBytes("UTF-8");            // Chrome/Firefox/Safari
            String encodedName = new String(nameBytes, "ISO-8859-1");
            resp.setHeader("Content-Disposition",
                    String.format("attachment; filename=\"%s\"", encodedName));

            byte[] buf = new byte[2048];
            int read;
            while ((read = bis.read(buf)) != -1) bos.write(buf, 0, read);
        }
    }

    // 重載:不指定文件名,取原文件名
    public static void download(HttpServletRequest req, HttpServletResponse resp, String filePath) throws IOException {
        download(req, resp, filePath, new File(filePath).getName());
    }
}

前端調用

// 雙重 encodeURI 確保參數傳遞不亂碼
function download(fileName, dir) {
    window.location.href = basePath + "/download?dir=" + dir
        + "&fileName=" + encodeURI(encodeURI(fileName));
}

Controller 層

@GetMapping("/download")
public void download(@RequestParam String dir, @RequestParam String fileName,
                     HttpServletRequest req, HttpServletResponse resp) throws Exception {
    String decoded = URLDecoder.decode(fileName, "UTF-8");
    String base = req.getSession().getServletContext().getRealPath("/WEB-INF/");
    String folder = "upload".equals(dir) ? "upload" : "download";
    DownloadUtils.download(req, resp, base + folder + "/" + decoded, decoded);
}

MIME 類型說明

multipart/form-data 為通用二進制流,瀏覽器會彈出下載框而非嘗試打開。若需精確類型,可用 MimetypesFileTypeMap 自動檢測。

亂碼三層防線

  1. 前端雙重 encodeURI + 後端 URLDecoder.decode
  2. 文件存儲系統編碼統一 UTF-8
  3. 響應頭 Content-Disposition 針對 UA 區分編碼策略
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved