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

Java 整合 WebUploader 實現大文件分片上傳(單文件/多文件)完整實戰

     編輯:Java 相關知識

項目背景與技術選型

原系統使用 ajaxFileUpload 上傳 2GB 文件無問題,但客戶後續需求上傳 4GB 甚至 20GB 文件。在 IE11(32位)下,ajaxFileUpload 會拋出「算術結果超過 32 位」異常。經調研,選擇百度 WebUploader(HTML5 + Flash 双模式),支持分片並發上傳,兼容 IE6+、iOS 6+、Android 4+,且可自定義 UI 樣式。

前端集成要點

1. 引入資源

<link rel="stylesheet" href="webuploader.css">
<script src="jquery.min.js"></script>
<script src="webuploader.min.js"></script>

Uploader.swf 由 WebUploader 內部加載,初始化時指定 swf 路徑即可。

2. 單文件上傳配置

var uploader = WebUploader.create({
    auto: false,                    // 手動觸發上傳
    pick: { id: '#attach', multiple: false },
    swf: '../../main/js/Uploader.swf',
    server: 'ContentsDetail!ajaxAttachUpload.action',
    chunked: true,                  // 啟用分片
    chunkSize: 5 * 1024 * 1024,     // 5MB/片
    threads: 1,                     // 串行上傳,保證順序
    formData: {                     // 額外表單字段
        status: 'file',
        'contentsDto.contentsId': '0000004730',
        uploadNum: '0000004730',
        existFlg: 'false'
    },
    disableGlobalDnd: true          // 禁用全局拖拽
});

3. 關鍵事件處理

  • fileQueued:文件加入隊列,渲染列表 UI。
  • uploadAccept:服務端響應校驗,非成功碼則 return false 中斷並 reset。
  • uploadSuccess/Error:更新狀態文案,失敗時 cancelFile + removeFile + reset。
  • 點擊「上傳」按鈕調用 uploader.upload()。

4. 多文件上傳差異

  • pick.multiple: true,name: 'multiFile'。
  • startUpload 事件中彙總所有文件大小、名稱,通過 formData 一次性傳給後端。
  • 錯誤處理需遍歷 uploader.getFiles() 清理所有文件。

後端實現(Struts2 + 自定義工具類)

1. 分片合併邏輯

public void ajaxAttachUpload() {
    String path = "d:\\test\\" + fileFileName;
    try {
        File temp = this.getFile(); // Struts2 自動注入上傳臨時文件
        FileUtil.randomAccessFile(path, temp); // 斷點續寫核心

        if (StringUtils.isEmpty(chunk)) { // 單片/小文件
            outJson("0", "success", "");
        } else if (Integer.parseInt(chunk) == Integer.parseInt(chunks) - 1) { // 最後一片
            outJson("0", "上傳成功", "");
        } else {
            outJson("2", "上傳中 chunk:" + chunk, "");
        }
    } catch (Exception e) {
        outJson("3", "上傳失敗", "");
    }
}

2. 隨機寫入工具類

public static void randomAccessFile(String outPath, File src) throws IOException {
    try (RandomAccessFile raf = new RandomAccessFile(new File(outPath), "rw");
         BufferedInputStream in = new BufferedInputStream(new FileInputStream(src))) {
        raf.seek(raf.length()); // 定位到文件末尾(追加模式)
        byte[] buf = new byte[1024];
        int len;
        while ((len = in.read(buf)) != -1) {
            raf.write(buf, 0, len);
        }
    }
}

關鍵點:RandomAccessFile 的 seek(length()) 實現斷點續傳;多線程並發上傳同一文件時需加鎖(此處 threads:1 避開並發問題)。

常見坑與優化建議

  1. IE 32 位限制:WebUploader HTML5 模式下,大文件分片在瀏覽器端切片,不佔用大內存,繞過 32 位限制。
  2. 文件名衝突:後端建議用 UUID + 原文件名 存儲,避免覆蓋。
  3. 秒傳/斷點續傳:需前端計算文件 MD5(WebUploader 支持 checkChunk),後端維護已上傳分片記錄。
  4. 臨時文件清理:上傳失敗或取消時,調用 item.delete() 刪除 WebUploader 產生的臨時分片文件。
  5. 進度條實現:監聽 uploadProgress 事件,根據 file.loaded / file.size 更新 UI。

總結

WebUploader 憑藉分片並發、良好兼容性、靈活 API,成為 Java 後端大文件上傳的首選方案。前端配置分片參數,後端用 RandomAccessFile 追寫合併,即可穩健支撐 20GB+ 文件上傳。生產環境建議補全 MD5 秒傳、分片校驗、異常重試、存儲服務解耦(如對接 OSS)等能力。

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