1. 程式人生 > >使用百度webuploader實現大檔案上傳

使用百度webuploader實現大檔案上傳

 寫在前面

          後臺的上傳檔案,都是50M左右比較小,後面說需要上傳大一點500M以上的,一直沒整過這方面的,昨天在網上看下其他人的實現方式,東看看西借鑑之後就有了下面的東西

第一部分 頁面

        頁面實現了簡單的分片上傳檔案

        formData 裡面的guid 對應下面第二部分 bigFile方法裡面的guid 作為分片上傳檔案是 分片檔名稱字首和用於後面合併分片 如下圖

               

      同時 formData裡面可以附帶的傳遞引數給後臺

      具體引數說明可以參考 點選開啟連結

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link href="https://cdn.staticfile.org/webuploader/0.1.5/webuploader.css"
	rel="stylesheet" type="text/css" />
<script type="text/javascript"
	src="http://cdn.staticfile.org/jquery/1.10.2/jquery.js"></script>
<script type="text/javascript"
	src="http://cdn.staticfile.org/webuploader/0.1.5/webuploader.min.js"></script>
</head>
<body>
	<div id="uploader" class="wu-example">
		<!--用來存放檔案資訊-->
		<div id="thelist" class="uploader-list"></div>
		<div class="btns">
			<div id="picker">選擇檔案</div>
			<button id="ctlBtn" class="btn btn-default">開始上傳</button>
		</div>
	</div>
</body>
<script type="text/javascript">
var GUID = WebUploader.Base.guid();//一個GUID
var uploader = WebUploader.create({
    // swf檔案路徑
    swf: 'http://cdn.staticfile.org/webuploader/0.1.5/Uploader.swf',
    // 檔案接收服務端。
    server: './uploadFile/bigFile.do',
    formData:{
    	guid : GUID
    },
    // 選擇檔案的按鈕。可選。
    pick: '#picker',
	chunked : true, // 分片處理
	chunkSize : 35 * 1024 * 1024, // 每片35M,
	chunkRetry : false,// 如果失敗,則不重試
	threads : 1,// 上傳併發數。允許同時最大上傳程序數。
    // 不壓縮image, 預設如果是jpeg,檔案上傳前會壓縮一把再上傳!
    resize: false
});
$("#ctlBtn").click(function () {
   uploader.upload();
});
//當檔案上傳成功時觸發。
uploader.on( "uploadSuccess", function( file ) {
	 $.post('./uploadFile/mergeFile.do', { guid: GUID, fileName: file.name }, function (data) {
		 var result = data.results;
		 if(result.code == 200){
			 alert('上傳成功!');
		 }
     });
});
</script>
</html>

第二部分 後臺接受分片檔案和合並檔案

         分為上傳檔案和合並檔案

         filePath 為配置檔案裡面上傳檔案路徑

package com.upload.bigfile.controller;

import java.io.File;
import java.io.FileOutputStream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.upload.bigfile.util.JsonResult;

@Controller
@RequestMapping( value = "/uploadFile" )
public class UploadController extends BaseController{
    
    @Value("${uploadFolder}")
    private String filePath;
    
    /**
     * 上傳檔案
     * @param request
     * @param response
     * @param guid  當前上傳檔案GUID
     * @param chunk 第幾個分片
     * @param file    第幾個分片檔案
     * @param chunks 總分片數量
     */
    @RequestMapping( value = "/bigFile")
    public void bigFile(HttpServletRequest request, HttpServletResponse response,String guid,Integer chunk, MultipartFile file,Integer chunks){
        try {  
            boolean isMultipart = ServletFileUpload.isMultipartContent(request);  
            if (isMultipart) {  
                // 臨時目錄用來存放所有分片檔案  
                String tempFileDir = filePath + guid;  
                File parentFileDir = new File(tempFileDir);  
                if (!parentFileDir.exists()) {  
                    parentFileDir.mkdirs();  
                }  
                // 分片處理時,前臺會多次呼叫上傳介面,每次都會上傳檔案的一部分到後臺  
                File tempPartFile = new File(parentFileDir, guid + "_" + chunk + ".part");  
                FileUtils.copyInputStreamToFile(file.getInputStream(), tempPartFile);  
            }  
        } catch (Exception e) {  
            e.printStackTrace();
        }  
    }
    
    /**
     * 組合檔案
     * @param guid
     * @param fileName
     * @throws Exception
     */
    @RequestMapping( value = "/mergeFile")
    @ResponseBody
    public void mergeFile(String guid,String fileName){
         // 得到 destTempFile 就是最終的檔案  
        JsonResult jsonReulst = new JsonResult();
        try {
            File parentFileDir = new File(filePath + guid);
            if(parentFileDir.isDirectory()){
                File destTempFile = new File(filePath + "/merge", fileName);  
                for (int i = 0; i < parentFileDir.listFiles().length; i++) {  
                    File partFile = new File(parentFileDir, guid + "_" + i + ".part");  
                    FileOutputStream destTempfos = new FileOutputStream(destTempFile, true);  
                    //遍歷"所有分片檔案"到"最終檔案"中  
                    FileUtils.copyFile(partFile, destTempfos);  
                    destTempfos.close();  
                }  
                // 刪除臨時目錄中的分片檔案  
                FileUtils.deleteDirectory(parentFileDir);
                this.successFormat(jsonReulst);
            }
        } catch (Exception e) {
            e.printStackTrace();
            this.failFormat(jsonReulst);
        }
          
    }
}