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

基於 HTML5 與 Java 實現大文件上傳完整實例

     編輯:Java 相關知識

方案概述

本文提供一套基於 HTML5 FormData + XMLHttpRequest 前端,配合 Java Servlet(Apache Commons FileUpload)後端的大文件上傳完整示例。支持超 1GB 大文件,採用流式寫入避免內存溢出。

前端實現(HTML + JavaScript)

<input id="fileid" type="file" accept="video/*;capture=camera" onchange="onfile(this)">
<input id="btn" type="button" value="提交">
<script>
var xhr;
function onfile(file) {
    var fd = new FormData();
    fd.append("fileToUpload", document.getElementById('fileid').files[0]);
    xhr = new XMLHttpRequest();
    xhr.open("POST", "https://localhost:8889/TestUp/upservlet");
    // 注意:不可手動設置 Content-Type,瀏覽器會自動生成 multipart/form-data 邊界
    xhr.send(fd);
    xhr.onreadystatechange = processResponse;
}
function processResponse() {
    if (xhr.readyState == 4) {
        if (xhr.status == 200) alert("服務器響應: " + xhr.responseText);
        else alert("上傳失敗");
    }
}
</script>

關鍵點:FormData 自動處理 multipart/form-data 編碼;切勿手動設置 Content-Type,否則會導致邊界缺失解析失敗。

後端實現(Java Servlet)

依賴兩個 JAR:commons-fileupload-1.2.1.jar、commons-io-1.3.2.jar。

public class UpServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String savePath = getServletContext().getRealPath("/WEB-INF/upload");
        File dir = new File(savePath);
        if (!dir.exists()) dir.mkdirs();

        DiskFileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload upload = new ServletFileUpload(factory);
        upload.setHeaderEncoding("UTF-8"); // 解決文件名中文亂碼

        if (!ServletFileUpload.isMultipartContent(request)) return;

        List<FileItem> items = upload.parseRequest(request);
        for (FileItem item : items) {
            if (item.isFormField()) {
                // 普通表單字段處理
                String value = item.getString("UTF-8");
            } else {
                // 文件字段處理
                String filename = item.getName();
                if (filename == null || filename.trim().isEmpty()) continue;
                // 截取純文件名(去除路徑)
                filename = filename.substring(filename.lastIndexOf("\\") + 1);
                
                try (InputStream in = item.getInputStream();
                     FileOutputStream out = new FileOutputStream(savePath + File.separator + filename)) {
                    byte[] buffer = new byte[1024 * 1024]; // 1MB 緩衝區
                    int len;
                    while ((len = in.read(buffer)) > 0) {
                        out.write(buffer, 0, len);
                    }
                }
                item.delete(); // 清理臨時文件
            }
        }
        request.setAttribute("message", "上傳成功");
        request.getRequestDispatcher("/message.jsp").forward(request, response);
    }
}

大文件上傳關鍵優化

  • 流式處理:使用 FileItem.getInputStream() 逐塊讀取,避免全量載入內存。
  • 大緩衝區:1MB 緩衝區減少系統調用開銷。
  • 臨時文件清理:item.delete() 釋放磁盤空間。
  • 編碼統一:upload.setHeaderEncoding("UTF-8") 解決文件名亂碼。
  • 安全存儲:文件保存在 WEB-INF 下,防止直接外部訪問。

常見問題排查

  1. 上傳失敗無報錯:檢查 web.xml 中 Servlet 映射、max-file-size/max-request-size 限制。
  2. 中文文件名亂碼:確保前端頁面 <meta charset="UTF-8">,後端 setHeaderEncoding("UTF-8")。
  3. 超大文件內存溢出:調整 DiskFileItemFactory 閾值,超過閾值寫入臨時文件而非內存。

此方案經測試可穩定支持 1GB+ 視頻文件上傳,適合內部管理系統、素材庫等場景。生產環境建議增加斷點續傳、MD5 秒傳、分片上傳等增強功能。

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