Java中使用WebUploader插件上傳大文件單文件和多文件的方法小結(jié)
一.使用webuploader插件的原因說明
被現(xiàn)在做的項目坑了。
先說一下我的項目架構(gòu)spring+struts2+mybatis+MySQL
然后呢。之前說好的按照2G上傳就可以了,于是乎,用了ajaxFileUpload插件,因為之前用圖片上傳也是用這個,所以上傳附件的時候就直接拿來用了
各種碼代碼,測試也測過了,2G文件上傳沒問題,坑來了,項目上線后,客戶又要求上傳4G文件,甚至還有20G以上的。。納尼,你不早說哦。。。
在IE11下用ajaxFileUpload.js插件上傳超過4G的文件,IE直接拋出異常了。彈出 算術結(jié)果超過32位 的消息.
如下圖:
附加說明一下,我的系統(tǒng)是64位,8G內(nèi)存,google瀏覽器和IE11瀏覽器都是32位的。google下用AjaxFileUpload上傳8G都問題。都不會報錯。
IE11下超過4G直接報上圖這個錯了。沒辦法。換插件。
二.插件選擇
1.stream上傳插件。stream是解決不同瀏覽器上傳文件插件,是Uploadify的flash版和html5的結(jié)合。插件地址http://www.twinkling.cn/
功能確實很強大,不過CSS樣式固定死了,和我現(xiàn)在項目的進度條樣式很不一樣。還是放棄了這個插件
2.Webuploader 插件。WebUploader是由Baidu WebFE(FEX)團隊開發(fā)的一個簡單的以HTML5為主,F(xiàn)LASH為輔的現(xiàn)代文件上傳組件。在現(xiàn)代的瀏覽器里面能充分發(fā)揮HTML5的優(yōu)勢,同時又不摒棄主流IE瀏覽器,沿用原來的FLASH運行時,兼容IE6+,iOS 6+, Android 4+。兩套運行時,同樣的調(diào)用方式,可供用戶任意選用。
采用大文件分片并發(fā)上傳,極大的提高了文件上傳效率。插件地址 http://fex.baidu.com/webuploader/
這個插件可以自定義CSS樣式啊。功能也很強大,于是乎果斷采用這個插件。
三.WebUploader 單文件上傳
我用的是Webuploader0.1.5版本的,Webuploader主要是把大文件在客戶端進行分片,比如按照每5M進行分片發(fā)送請求,后臺接收到文件進行合并文件。兩種方式合并文件,第一種等所有分片都傳到后臺,然后在合并,這種要保障分片順序正確,第二種是邊分片邊合并。項目里我使用的是第二種。使用Web Uploader文件上傳需要引入三種資源:JS, CSS, SWF。
1.引入JS文件
<script type="text/javascript" src="../main/js/webuploader.js"></script> <script type="text/javascript" src="../main/js/webuploader.min.js"></script>
2.引入CSS樣式
<link href="../main/css/webuploader.css" rel="stylesheet" type="text/css" />
3.引入SWF,SWF不直接引用,在webUploader初始化的時候指定SWF的路徑就可以了。
4.upload3.html
<!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" xml:lang="ja" lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> <meta http-equiv="Content-Language" content="ja" /> <meta http-equiv="Content-Script-Type" content="text/javascript" /> <meta http-equiv="Content-Style-Type" content="text/css" /> <title>DEMO</title> <link href="../main/css/stream-v1.css" rel="stylesheet" type="text/css" /> <link href="../main/css/webuploader.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="../main/js/jquery-1.11.1.min.js"></script> <script type="text/javascript" src="../main/js/jquery-2.1.4.min.js"></script> <script type="text/javascript" src="../main/js/jquery-ui.min.js"></script> <script type="text/javascript" src="../main/js/bootstrap-datepicker.min.js"></script> <script type="text/javascript" src="../main/js/locales/bootstrap-datepicker.ja.min.js"></script> <script type="text/javascript" src="../main/js/webuploader.js"></script> <script type="text/javascript" src="../main/js/webuploader.min.js"></script> <script type="text/javascript" src="../js/contents/upload3.js"></script> </head> <body> <div id="uploader" class="wu-example"> <!--用來存放文件信息--> <div id="thelist" class="uploader-list"></div> <div class="btns"> <div id="attach"></div> <input type="button" value="上傳" id="upload"/> </div> </div> <div id="uploader1" class="wu-example"> <!--用來存放文件信息--> <div id="thelist1" class="uploader-list"></div> <div class="btns"> <div id="multi"></div> <input type="button" value="上傳" id="multiUpload"/> </div> </div> </body> </html>
畫面比較簡單,長這個樣子
5.upload3.js
包含單文件上傳,多文件上傳,和webuploader多實例
/*********************************WebUpload 單文件上傳 begin*****************************************/
$(function(){
var $list = $("#thelist");
var uploader ;// 實例化
uploader = WebUploader.create({
auto:false, //是否自動上傳
pick: {
id: '#attach',
name:"file", //這個地方 name 沒什么用,雖然打開調(diào)試器,input的名字確實改過來了。但是提交到后臺取不到文件。如果想自定義file的name屬性,還是要和fileVal 配合使用。
label: '點擊選擇圖片',
multiple:false //默認為true,就是可以多選
},
swf: '../../main/js/Uploader.swf',
//fileVal:'multiFile', //自定義file的name屬性,我用的版本是0.1.5 ,打開客戶端調(diào)試器發(fā)現(xiàn)生成的input 的name 沒改過來。
//名字還是默認的file,但不是沒用哦。雖然客戶端名字沒改變,但是提交到到后臺,是要用multiFile 這個對象來取文件的,用file 是取不到文件的
// 建議作者有時間把這個地方改改啊,搞死人了。。
server: "ContentsDetail!ajaxAttachUpload.action",
duplicate:true,//是否可重復選擇同一文件
resize: false,
formData: {
"status":"file",
"contentsDto.contentsId":"0000004730",
"uploadNum":"0000004730",
"existFlg":'false'
},
compress: null,//圖片不壓縮
chunked: true, //分片處理
chunkSize: 5 * 1024 * 1024, //每片5M
chunkRetry:false,//如果失敗,則不重試
threads:1,//上傳并發(fā)數(shù)。允許同時最大上傳進程數(shù)。
// runtimeOrder: 'flash',
// 禁掉全局的拖拽功能。這樣不會出現(xiàn)圖片拖進頁面的時候,把圖片打開。
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>" );
});
//當所有文件上傳結(jié)束時觸發(fā)
uploader.on("uploadFinished",function(){
console.log("uploadFinished:");
})
//當某個文件上傳到服務端響應后,會派送此事件來詢問服務端響應是否有效。
uploader.on("uploadAccept",function(object,ret){
//服務器響應了
//ret._raw 類似于 data
var data =JSON.parse(ret._raw);
if(data.resultCode != "1" && data.resultCode != "3"){
if(data.resultCode == "9"){
uploader.reset();
alert("error");
return false;
}
}else{
//E05017
uploader.reset();
alert("error");
return false;
}
})
//當文件上傳成功時觸發(fā)。
uploader.on( "uploadSuccess", function( file ) {
$( "#"+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();
});
$("#upload").on("click", function() {
uploader.upload();
})
});
/*********************************WebUpload 單文件上傳 end*******************************************/
/*********************************WebUpload 多文件上傳 begin*****************************************/
$(function(){
var $list = $("#thelist1");
var fileSize = 0; //總文件大小
var fileName = []; //文件名列表
var fileSizeOneByOne =[];//每個文件大小
var uploader ;// 實例化
uploader = WebUploader.create({
auto:false, //是否自動上傳
pick: {
id: '#multi',
label: '點擊選擇文件',
name:"multiFile"
},
swf: '../../main/js/Uploader.swf',
server: "ContentsDetail!multiUpload.action",
duplicate:true, //同一文件是否可重復選擇
resize: false,
formData: {
"status":"multi",
"contentsDto.contentsId":"0000004730",
"uploadNum":"0000004730",
"existFlg":'false'
},
compress: null,//圖片不壓縮
chunked: true, //分片
chunkSize: 5 * 1024 * 1024, //每片5M
chunkRetry:false,//如果失敗,則不重試
threads:1,//上傳并發(fā)數(shù)。允許同時最大上傳進程數(shù)。
//fileNumLimit:50,//驗證文件總數(shù)量, 超出則不允許加入隊列
// runtimeOrder: 'flash',
// 禁掉全局的拖拽功能。這樣不會出現(xiàn)圖片拖進頁面的時候,把圖片打開。
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>" );
});
// 當開始上傳流程時觸發(fā)
uploader.on( "startUpload", function() {
console.log("startUpload");
//添加額外的表單參數(shù)
$.extend( true, uploader.options.formData, {"fileSize":fileSize,"multiFileName":fileName.join(","),"fileSizeOneByOne":fileSizeOneByOne.join(",")});
});
//當某個文件上傳到服務端響應后,會派送此事件來詢問服務端響應是否有效。
uploader.on("uploadAccept",function(object,ret){
//服務器響應了
//ret._raw 類似于 data
console.log("uploadAccept");
console.log(ret);
var data =JSON.parse(ret._raw);
if(data.resultCode!="1" && data.resultCode !="3"){
if(data.resultCode == "9"){
alert("error");
uploader.reset();
return;
}
}else{
uploader.reset();
alert("error");
}
})
uploader.on( "uploadSuccess", function( file ) {
$( "#"+file.id ).find("p.state").text("已上傳");
});
uploader.on( "uploadError", function( file,reason ) {
$( "#"+file.id ).find("p.state").text("上傳出錯");
console.log("uploadError");
console.log(file);
console.log(reason);
//多個文件
var fileArray = uploader.getFiles();
for(var i = 0 ;i<fileArray.length;i++){
uploader.cancelFile(fileArray[i]);
uploader.removeFile(fileArray[i],true);
}
uploader.reset();
fileSize = 0;
fileName = [];
fileSizeOneByOne=[];
});
//當validate不通過時,會以派送錯誤事件的形式通知調(diào)用者
uploader.on("error",function(){
console.log("error");
uploader.reset();
fileSize = 0;
fileName = [];
fileSizeOneByOne=[];
alert("error");
})
//如果是在模態(tài)框里的上傳按鈕,點擊file的時候不會觸發(fā)控件
//修復model內(nèi)部點擊不會觸發(fā)選擇文件的BUG
/* $("#multi .webuploader-pick").click(function () {
uploader.reset();
fileSize = 0;
fileName = [];
fileSizeOneByOne=[];
$("#multi :file").click();//關鍵代碼
});*/
//選擇文件之后執(zhí)行上傳
$(document).on("change","input[name='multiFile']", function() {
var fileArray1 = uploader.getFiles();
for(var i = 0 ;i<fileArray1.length;i++){
//后臺用
fileSize +=fileArray1[i].size;
fileSizeOneByOne.push(fileArray1[i].size);
fileName.push(fileArray1[i].name);
}
console.log(fileSize);
console.log(fileSizeOneByOne);
console.log(fileName);
})
/**
* 多文件上傳
*/
$("input[name='multiUpload']").on("click",function(){
uploader.upload();
})
});
/*********************************WebUpload 多文件上傳 end*****************************************/
/************************************webuploader的自帶參數(shù)提交到后臺的參數(shù)列表*************************
* {
//web uploader 的自帶參數(shù)
lastModifiedDate=[Wed Apr 27 2016 16:45:01 GMT+0800 (中國標準時間)],
chunks=[3], chunk=[0],
type=[audio/wav], uid=[yangl], id=[WU_FILE_0],
size=[268620636], name=[3.wav],
//formData的參數(shù)
contentsDto.contentsId=[0000004730], existFlg=[false],
status=[file], uploadNum=[0000004730]
}
*********************************************************************************************/
6.ContentsDetail.action
//單文件上傳后臺代碼
public void ajaxAttachUpload() {
String path = "d:\\test\\"+fileFileName;
try {
File file = this.getFile();
FileUtil.randomAccessFile(path, file);
//如果文件小與5M的話,分片參數(shù)chunk的值是null
if(StringUtils.isEmpty(chunk)){
outJson("0", "success", "");
}else{
//chunk 分片索引,下標從0開始
//chunks 總分片數(shù)
if (Integer.valueOf(chunk) == (Integer.valueOf(chunks) - 1)) {
outJson("0", "上傳成功", "");
} else {
outJson("2", "上傳中" + fileFileName + " chunk:" + chunk, "");
}
}
} catch (Exception e) {
outJson("3", "上傳失敗", "");
}
}
FileUtil.java
/**
* 指定位置開始寫入文件
* @param tempFile 輸入文件
* @param outPath 輸出文件的路徑(路徑+文件名)
* @throws IOException
*/
public static void randomAccessFile( String outPath,File tempFile) throws IOException{
RandomAccessFile raFile = null;
BufferedInputStream inputStream=null;
try{
File dirFile = new File(outPath);
//以讀寫的方式打開目標文件
raFile = new RandomAccessFile(dirFile, "rw");
raFile.seek(raFile.length());
inputStream = new BufferedInputStream(new FileInputStream(tempFile));
byte[] buf = new byte[1024];
int length = 0;
while ((length = inputStream.read(buf)) != -1) {
raFile.write(buf, 0, length);
}
}catch(Exception e){
throw new IOException(e.getMessage());
}finally{
try {
if (inputStream != null) {
inputStream.close();
}
if (raFile != null) {
raFile.close();
}
}catch(Exception e){
throw new IOException(e.getMessage());
}
}
}
7.效果圖

以上所述是小編給大家介紹的Java中使用WebUploader插件上傳大文件單文件和多文件的方法小結(jié)的相關知識,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關文章
SpringMvc/SpringBoot HTTP通信加解密的實現(xiàn)
這篇文章主要介紹了SpringMvc/SpringBoot HTTP通信加解密的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-08-08
SpringBoot2 集成log4j2日志框架的實現(xiàn)
這篇文章主要介紹了SpringBoot2 集成log4j2日志框架的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-10-10
MyBatis開發(fā)Dao層的兩種方式實現(xiàn)(原始Dao層開發(fā))
這篇文章主要介紹了MyBatis開發(fā)Dao層的兩種方式實現(xiàn)(原始Dao層開發(fā)),并對數(shù)據(jù)庫進行增刪查改,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-12-12
Graceful Response 構(gòu)建 Spring Boot 響應
Graceful Response是一個Spring Boot技術棧下的優(yōu)雅響應處理器,提供一站式統(tǒng)一返回值封裝、全局異常處理、自定義異常錯誤碼等功能,本文介紹Graceful Response 構(gòu)建 Spring Boot 下優(yōu)雅的響應處理,感興趣的朋友一起看看吧2024-01-01

