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

WebUploader + Spring MVC 實現大文件分片上傳:前端組件配置與後端合並存儲全流程

     編輯:Java 相關知識

技術選型理由

  • Baidu WebUploader:HTML5 主流 + Flash 降級,支持 IE6+、iOS 6+、Android 4+
  • 核心優勢:大文件分片並發上傳、斷點續傳、拖拽/截圖粘貼、縮略圖預覽
  • 僅提供底層邏輯,UI 完全可定制

前端核心配置

HTML 結構

<div id="uploader" class="wu-example">
  <div class="queueList">
    <div id="dndArea" class="placeholder">
      <div id="filePicker"></div>
      <p>或將照片拖到這裡,單次最多可選 300 張</p>
    </div>
  </div>
  <div class="statusBar">
    <div class="progress"><span class="text">0%</span></div>
    <div class="info"></div>
    <div class="btns">
      <div id="filePicker2"></div>
      <div class="uploadBtn">開始上傳</div>
    </div>
  </div>
</div>

JavaScript 初始化關鍵參數

var uploader = WebUploader.create({
    // 選文件按鈕
    pick: { id: '#filePicker', label: '點擊選擇圖片' },
    // 拖拽區域
    dnd: '#uploader .queueList',
    // 截圖粘貼
    paste: document.body,
    // 文件類型過濾
    accept: {
        title: 'Images',
        extensions: 'gif,jpg,jpeg,bmp,png',
        mimeTypes: 'image/*'
    },
    // Flash 降級路徑
    swf: 'js/plugins/webuploader/Uploader.swf',
    disableGlobalDnd: true,
    // ★ 分片上傳核心
    chunked: true,
    chunkSize: 5 * 1024 * 1024, // 5MB/片
    threads: 3,                 // 並發分片數
    // 後端接收地址
    server: 'https://localhost:8080/test/upload.do?method=upload',
    // 限制
    fileNumLimit: 300,
    fileSizeLimit: 200 * 1024 * 1024, // 200MB 總大小
    fileSingleSizeLimit: 50 * 1024 * 1024 // 50MB 單文件
});

狀態管理與 UI 交互(精簡版)

// 文件加入隊列
uploader.onFileQueued = function(file) {
    fileCount++; fileSize += file.size;
    renderFileItem(file); // 創建 li、生成縮略圖、綁定刪除/旋轉
    updateStatus('ready');
};

// 上傳進度
uploader.onUploadProgress = function(file, percentage) {
    $('#'+file.id).find('.progress span').css('width', percentage*100+'%');
    updateTotalProgress();
};

// 狀態機:pedding → ready → uploading → paused → confirm → finish
function setState(val) {
    // 切換按鈕文本、顯隱進度條、刷新 uploader
}

後端 Spring MVC 實現

分片接收與合並控制器

@Controller
@RequestMapping("/upload")
public class UploadController {
    private static final String UPLOAD_ROOT = "/data/upload/";
    private static final String TEMP_DIR = UPLOAD_ROOT + "temp/";
    private static final String FINAL_DIR = UPLOAD_ROOT + "files/";

    @RequestMapping(params = "method=upload")
    @ResponseBody
    public String upload(@RequestParam("file") MultipartFile chunk,
                         @RequestParam("chunk") Integer chunkIndex,
                         @RequestParam("chunks") Integer totalChunks,
                         @RequestParam("name") String fileName,
                         @RequestParam("md5") String fileMd5) {
        
        // 1. 分片臨時存儲:temp/{md5}/{chunk}
        File tempFile = new File(TEMP_DIR + fileMd5 + "/" + chunkIndex);
        tempFile.getParentFile().mkdirs();
        try { chunk.transferTo(tempFile); } 
        catch (IOException e) { return jsonError("分片存儲失敗"); }

        // 2. 最後一片 → 合並
        if (chunkIndex == totalChunks - 1) {
            File finalFile = new File(FINAL_DIR + fileName);
            try (FileOutputStream fos = new FileOutputStream(finalFile)) {
                for (int i = 0; i < totalChunks; i++) {
                    File part = new File(TEMP_DIR + fileMd5 + "/" + i);
                    Files.copy(part.toPath(), fos);
                    part.delete(); // 清理分片
                }
                new File(TEMP_DIR + fileMd5).delete(); // 清理目錄
            } catch (IOException e) { return jsonError("合並失敗"); }
            
            // 3. 入庫記錄(路徑、MD5、大小、類型...)
            // fileService.save(...);
        }
        return jsonSuccess();
    }

    private String jsonSuccess() { return "{\"msg\":\"success\"}"; }
    private String jsonError(String msg) { return "{\"msg\":\"error\",\"error\":\""+msg+"\"}"; }
}

Spring MVC 文件上傳配置

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="52428800"/> <!-- 50MB 單片上限 -->
    <property name="maxInMemorySize" value="4096"/>
</bean>

斷點續傳增強(可選)

  1. 上傳前調用 uploader.md5File(file) 計算文件 MD5(WebUploader 內置 SparkMD5)
  2. 前端發送 md5 參數,後端檢查 temp/{md5}/ 目錄下已存在分片
  3. 跳過已上傳分片,僅上傳缺失部分
  4. 秒傳邏輯:最終目錄存在同 MD5 文件 → 直接返回成功

生產部署注意事項

  • Nginx 反代:設置 client_max_body_size 50M; proxy_read_timeout 300s;
  • 臨時目錄清理:定時任務清理 24h 前未完成的 temp/ 目錄
  • 文件名安全:存儲用 UUID/MD5 命名,原始名存數據庫,防路徑遍歷
  • 權限控制:上傳接口需認證,限制用戶配額
  • 集群共享存儲:多實例需掛載 NFS/NAS 或對象存儲(S3/OSS)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved