一.使用webuploader插件的原因說明
被現在做的項目坑了。
先說一下我的項目架構spring+struts2+mybatis+MySQL
然后呢。之前說好的按照2G上傳就可以了,于是乎,用了ajaxFileUpload插件,因為之前用圖片上傳也是用這個,所以上傳附件的時候就直接拿來用了
各種碼代碼,測試也測過了,2G文件上傳沒問題,坑來了,項目上線后,客戶又要求上傳4G文件,甚至還有20G以上的。。納尼,你不早說哦。。。
在IE11下用ajaxFileUpload.js插件上傳超過4G的文件,IE直接拋出異常了。彈出 算術結果超過32位 的消息.
如下圖:
附加說明一下,我的系統是64位,8G內存,google瀏覽器和IE11瀏覽器都是32位的。google下用AjaxFileUpload上傳8G都問題。都不會報錯。
IE11下超過4G直接報上圖這個錯了。沒辦法。換插件。
二.插件選擇
1.stream上傳插件。stream是解決不同瀏覽器上傳文件插件,是Uploadify的flash版和html5的結合。插件地址http://www.twinkling.cn/
功能確實很強大,不過CSS樣式固定死了,和我現在項目的進度條樣式很不一樣。還是放棄了這個插件
2.Webuploader 插件。WebUploader是由Baidu WebFE(FEX)團隊開發的一個簡單的以HTML5為主,FLASH為輔的現代文件上傳組件。在現代的瀏覽器里面能充分發揮HTML5的優勢,同時又不摒棄主流IE瀏覽器,沿用原來的FLASH運行時,兼容IE6+,iOS 6+, Android 4+。兩套運行時,同樣的調用方式,可供用戶任意選用。
采用大文件分片并發上傳,極大的提高了文件上傳效率。插件地址 http://fex.baidu.com/webuploader/
這個插件可以自定義CSS樣式啊。功能也很強大,于是乎果斷采用這個插件。
三.WebUploader 單文件上傳
我用的是Webuploader0.1.5版本的,Webuploader主要是把大文件在客戶端進行分片,比如按照每5M進行分片發送請求,后臺接收到文件進行合并文件。兩種方式合并文件,第一種等所有分片都傳到后臺,然后在合并,這種要保障分片順序正確,第二種是邊分片邊合并。項目里我使用的是第二種。使用Web Uploader文件上傳需要引入三種資源:JS, CSS, SWF。
1.引入JS文件
1
2
|
<script type= "text/javascript" src= "../main/js/webuploader.js" ></script> <script type= "text/javascript" src= "../main/js/webuploader.min.js" ></script> |
2.引入CSS樣式
1
|
<link href= "../main/css/webuploader.css" rel= "stylesheet" type= "text/css" /> |
3.引入SWF,SWF不直接引用,在webUploader初始化的時候指定SWF的路徑就可以了。
4.upload3.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
<!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多實例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|
/*********************************WebUpload 單文件上傳 begin*****************************************/ $( function (){ var $list = $( "#thelist" ); var uploader ; // 實例化 uploader = WebUploader.create({ auto: false , //是否自動上傳 pick: { id: '#attach' , name: "file" , //這個地方 name 沒什么用,雖然打開調試器,input的名字確實改過來了。但是提交到后臺取不到文件。如果想自定義file的name屬性,還是要和fileVal 配合使用。 label: '點擊選擇圖片' , multiple: false //默認為true,就是可以多選 }, swf: '../../main/js/Uploader.swf' , //fileVal:'multiFile', //自定義file的name屬性,我用的版本是0.1.5 ,打開客戶端調試器發現生成的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, //上傳并發數。允許同時最大上傳進程數。 // runtimeOrder: 'flash', // 禁掉全局的拖拽功能。這樣不會出現圖片拖進頁面的時候,把圖片打開。 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( "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 ; } }) //當文件上傳成功時觸發。 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, //上傳并發數。允許同時最大上傳進程數。 //fileNumLimit:50,//驗證文件總數量, 超出則不允許加入隊列 // runtimeOrder: 'flash', // 禁掉全局的拖拽功能。這樣不會出現圖片拖進頁面的時候,把圖片打開。 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( "startUpload" , function () { console.log( "startUpload" ); //添加額外的表單參數 $.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不通過時,會以派送錯誤事件的形式通知調用者 uploader.on( "error" , function (){ console.log( "error" ); uploader.reset(); fileSize = 0; fileName = []; fileSizeOneByOne=[]; alert( "error" ); }) //如果是在模態框里的上傳按鈕,點擊file的時候不會觸發控件 //修復model內部點擊不會觸發選擇文件的BUG /* $("#multi .webuploader-pick").click(function () { uploader.reset(); fileSize = 0; fileName = []; fileSizeOneByOne=[]; $("#multi :file").click();//關鍵代碼 });*/ //選擇文件之后執行上傳 $(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的自帶參數提交到后臺的參數列表************************* * { //web uploader 的自帶參數 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的參數 contentsDto.contentsId=[0000004730], existFlg=[false], status=[file], uploadNum=[0000004730] } *********************************************************************************************/ |
6.ContentsDetail.action
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
//單文件上傳后臺代碼 public void ajaxAttachUpload() { String path = "d:\\test\\" +fileFileName; try { File file = this .getFile(); FileUtil.randomAccessFile(path, file); //如果文件小與5M的話,分片參數chunk的值是null if (StringUtils.isEmpty(chunk)){ outJson( "0" , "success" , "" ); } else { //chunk 分片索引,下標從0開始 //chunks 總分片數 if (Integer.valueOf(chunk) == (Integer.valueOf(chunks) - 1)) { outJson( "0" , "上傳成功" , "" ); } else { outJson( "2" , "上傳中" + fileFileName + " chunk:" + chunk, "" ); } } } catch (Exception e) { outJson( "3" , "上傳失敗" , "" ); } } |
FileUtil.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
/** * 指定位置開始寫入文件 * @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插件上傳大文件單文件和多文件的方法小結的相關知識,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對服務器之家網站的支持!