一.使用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插件上传大文件单文件和多文件的方法小结的相关知识,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!