1. 程式人生 > >webuploader在springMVC+jquery+Java開發環境下的大檔案分片上傳

webuploader在springMVC+jquery+Java開發環境下的大檔案分片上傳

參考的文章http://blog.csdn.net/new_sara/article/details/51604997

因為從網上看到的總是和自己專案開發有些許差別,所以也是在除錯了很久之後,發現適合自己專案的程式碼,現在把過程記錄下來,以便以後查閱.

注意:

1,webuploader上傳元件會和jquery自帶的上傳元件衝突,所以不要使用<form>標籤中新增上傳檔案的屬性;

enctype="multipart/form-data"

2.並且遮蔽ApplicationContext-mvc.xml裡面的攔截配置!

<!-- 上傳攔截,如最大上傳值及最小上傳值 -->
	<!--新增加的webuploader上傳元件,必須要遮蔽這裡的攔截機制
	  <bean id="multipartResolver"   class="org.springframework.web.multipart.commons.CommonsMultipartResolver" >   
		  <property name="maxUploadSize">    
	          <value>1073741824</value>    
	       </property>   
	        <property name="maxInMemorySize">    
	            <value>1073741824</value>    
	        </property>   
	         <property name="defaultEncoding">    
	            <value>utf-8</value>    
	        </property> 
    </bean>  
	-->

下面正式開始前後臺程式碼開發:

1.在頁面jsp檔案中,呼叫webuploader元件的公共檔案

<link rel="stylesheet" href="static/css/webuploader.css" />
<script type="text/javascript" src="static/js/webuploader.js"></script>
		<script type="text/javascript" src="static/js/webuploader.min.js"></script>
		<script type="text/javascript" src="static/js/upload3.js"></script>

頁面上的控制元件程式碼:

<div id="uploader">
					    <!--用來存放檔案資訊-->
					    <div id="thelist"></div>
					    <div>
					        <div id="attach"></div>
					        <!--  <input type="button" value="上傳" id="upload"/> -->
					    </div>
					</div>

因為我用的是自動上傳,所以註釋了上傳按鈕,upload3.js裡也註釋了相對的上傳按鈕的點選方法.

2.真正的上傳元件程式碼是upload3.js,裡面介紹了webuploader的初始化,分片,各種引數,具體可以參考官網上的API

/*********************************WebUpload 單檔案上傳 begin*****************************************/
$(function(){
    var $list = $("#thelist");
    var  uploader ;// 例項化   
    uploader = WebUploader.create({ 
           auto:true, //是否自動上傳
            pick: {
                id: '#attach',
                name:"multiFile", //這個地方 name 沒什麼用,和fileVal 配合使用。
                label: '點選選擇檔案,會自動上傳',
                multiple:false  //預設為true,true表示可以多選檔案,HTML5的屬性
            },
            swf: '../Uploader.swf',  //在這裡必需要引入swf檔案,webuploader初始化要用
            fileVal:'multiFile',  //提交到到後臺,是要用"multiFile"這個名稱屬性來取檔案的
            server: "myPractice/webUploader.do",
            duplicate:true,//是否可重複選擇同一檔案
            resize: false,
            chunked: true,  //分片處理
            chunkSize: 20 * 1024 * 1024, //每片20M
            chunkRetry:2,//如果失敗,則不重試
            threads:1,//上傳併發數。允許同時最大上傳程序數。
            fileNumLimit:1,//上傳的檔案總數
            // 禁掉全域性的拖拽功能。
            disableGlobalDnd: true
        });  

       // 當有檔案新增進來的時候
       uploader.on( "fileQueued", function( file ) {
           console.log("fileQueued:");
           $list.append( "<div id='"+  file.id + "' class='item'>" +
               "<h4 class='info'>" + file.name + "</h4>" +
               "<p class='state'>正在上傳...</p>" +
           "</div>" );
       });

       //當所有檔案上傳結束時觸發
       uploader.on("uploadFinished",function(){
           console.log("uploadFinished:");
       })

       //當檔案上傳成功時觸發。
       uploader.on( "uploadSuccess", function( file ,response) {
//    	   alert(file.name);
           $( "#"+file.id ).find("p.state").text("已上傳");
       });

       uploader.on( "uploadError", function( file ) {
           $( "#"+file.id ).find("p.state").text("上傳出錯");
           uploader.cancelFile(file);
           uploader.removeFile(file,true);
           uploader.reset();
       });

       //如果是手動上傳,用下面的事件,並啟用jsp頁面上的上傳按鈕
//       $("#upload").on("click", function() {
//           uploader.upload();
//       })

});
/*********************************WebUpload 單檔案上傳 end*******************************************/


3.前臺完畢之後,需要找到後臺java程式碼,實現上傳到伺服器的功能,webuploader元件中server屬性就是指向服務端程式碼:

@Controller
@RequestMapping(value="/myPractice")//這裡就是表明上傳元件怎麼通過server屬性找到後端程式碼的,不要太在意細節
public class MyPracticeController extends BaseController {
@RequestMapping(method = {RequestMethod.POST}, value = {"/webUploader"})
@ResponseBody
public void webUploader(HttpServletRequest request, HttpServletResponse response) throws Exception {
	try {
            boolean isMultipart = ServletFileUpload.isMultipartContent(request);
            if (isMultipart) {
                FileItemFactory factory = new DiskFileItemFactory();
                ServletFileUpload upload = new ServletFileUpload(factory);
 
                // 得到所有的表單域,它們目前都被當作FileItem
                List<FileItem> fileItems = upload.parseRequest(request);
 
                String id = "";
                String fileName = "";
                // 如果大於1說明是分片處理
                int chunks = 1;
                int chunk = 0;
                FileItem tempFileItem = null;
 
                for (FileItem fileItem : fileItems) {
                    if (fileItem.getFieldName().equals("id")) {
                        id = fileItem.getString();
                    } else if (fileItem.getFieldName().equals("name")) {
                        fileName = new String(fileItem.getString().getBytes("ISO-8859-1"), "UTF-8");
                    } else if (fileItem.getFieldName().equals("chunks")) {
                        chunks = NumberUtils.toInt(fileItem.getString());
                    } else if (fileItem.getFieldName().equals("chunk")) {
                        chunk = NumberUtils.toInt(fileItem.getString());
                    } else if (fileItem.getFieldName().equals("multiFile")) {
                        tempFileItem = fileItem;
                    }
                }
                //session中的引數設定獲取是我自己的原因,檔名你們可以直接使用fileName,這個是原來的檔名
                String fileSysName = this.getRequest().getSession().getAttribute("fileSysName").toString();
                String realname = fileSysName+fileName.substring(fileName.lastIndexOf("."));//轉化後的檔名
                this.getRequest().getSession().setAttribute("realname",realname);
                String filePath = Const.VIDEOPATHFILE + "sound/";//檔案上傳路徑
                
                // 臨時目錄用來存放所有分片檔案
                String tempFileDir = filePath + id;
                File parentFileDir = new File(tempFileDir);
                if (!parentFileDir.exists()) {
                    parentFileDir.mkdirs();
                }
                // 分片處理時,前臺會多次呼叫上傳介面,每次都會上傳檔案的一部分到後臺
                File tempPartFile = new File(parentFileDir, realname + "_" + chunk + ".part");
                FileUtils.copyInputStreamToFile(tempFileItem.getInputStream(), tempPartFile);
 
                // 是否全部上傳完成
                // 所有分片都存在才說明整個檔案上傳完成
                boolean uploadDone = true;
                for (int i = 0; i < chunks; i++) {
                    File partFile = new File(parentFileDir, realname + "_" + i + ".part");
                    if (!partFile.exists()) {
                        uploadDone = false;
                    }
                }
                // 所有分片檔案都上傳完成
                // 將所有分片檔案合併到一個檔案中
                if (uploadDone) {
                	// 得到 destTempFile 就是最終的檔案
                    File destTempFile = new File(filePath, realname);
                    for (int i = 0; i < chunks; i++) {
                        File partFile = new File(parentFileDir, realname + "_" + i + ".part");
                        FileOutputStream destTempfos = new FileOutputStream(destTempFile, true);
                        //遍歷"所有分片檔案"到"最終檔案"中
                        FileUtils.copyFile(partFile, destTempfos);
                        destTempfos.close();
                    }
                    // 刪除臨時目錄中的分片檔案
                    FileUtils.deleteDirectory(parentFileDir);
                } else {
                    // 臨時檔案建立失敗
                    if (chunk == chunks -1) {
                        FileUtils.deleteDirectory(parentFileDir);
                    }
                }
                
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
}


到這裡基本完了,webuploader前後臺設計的程式碼就這些,

Uploader.swf   
webuploader.min.js
webuploader.js
webuploader.css
這4個公共檔案從官網可以下載,都一樣.
最後,檔案上傳後頁面樣式是