webuploader在springMVC+jquery+Java開發環境下的大檔案分片上傳
阿新 • • 發佈:2019-02-20
參考的文章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個公共檔案從官網可以下載,都一樣.
最後,檔案上傳後頁面樣式是