开发语言:JAVA
项目使用:Spring MVC + Spring
前端封装一个HDUpload函数,方便页面调用。项目不需要传图片,所以有关图片压缩之类的一些配置就没有写。
function HDUpload(){
var state = 'pending';
var uploader;
var init=function(dnd,server,pickObj,btnContent,multiple,accept,threadsNum,formData,fileQueued,uploadProgress,uploadSuccess,uploadError,uploadComplete){
// 初始化Web Uploader
uploader = WebUploader.create({
// 指定Drag And Drop拖拽的容器
dnd: dnd,
// swf文件路径
swf: basePath+'/statics/js/webuploader-0.1.5/Uploader.swf',
// 文件接收服务端。
server: server,
// 选择文件的按钮。可选。
// 内部根据当前运行时创建,可能是input元素,也可能是flash.
pick: {
id:pickObj,
innerHTML:btnContent,
multiple :multiple
},
// 是否要分片处理大文件上传,默认值:false
chunked:true,
// {Arroy} [可选] [默认值:null] 指定接受哪些类型的文件
accept:accept,
// 设置为 true 后,不需要手动调用上传,有文件选择即开始上传
auto:true,
// [可选] [默认值:3] 上传并发数。允许同时最大上传进程数。
threads:threadsNum,
// 去重, 根据文件名字、文件大小和最后修改时间来生成hash Key.
duplicate:true,
formData:formData
});
// 当有文件添加进来的时候
uploader.on('fileQueued', function(file) {
if(fileQueued)
fileQueued(file);
});
// 文件上传过程中创建进度条实时显示。
uploader.on('uploadProgress', function(file, percentage) {
if(uploadProgress)
uploadProgress(file, percentage);
});
//文件上传成功则派送uploadSuccess事件。
uploader.on( 'uploadSuccess', function( file,response ) {
if(uploadSuccess)
uploadSuccess(file,response);
});
//文件上传失败会派送uploadError事件
uploader.on( 'uploadError', function( file,reason ) {
if(uploadError)
uploadError(file,reason);
});
//不管成功或者失败,在文件上传完后都会触发uploadComplete事件
uploader.on( 'uploadComplete', function( file ) {
if(uploadComplete)
uploadComplete(file,uploader);
});
uploader.on('all', function(type) {
if(type === 'startUpload') {
state = 'uploading';
} else if(type === 'stopUpload') {
state = 'paused';
} else if(type === 'uploadFinished') {
state = 'done';
}
});
};
return {init:init};
};
函数调用方法:
var dnd=null;
var server=type=='/file/upload';
var pickObj='.picker';
var btnContent='点击上传';
var multiple=false;
var accept=null;
var threadsNum=3;
var formData={stdId:stdId};
new HDUpload().init(dnd,server,pickObj,btnContent,
multiple,accept,threadsNum,formData,
function(file) {
//fileQueued
....
},function(file, percentage) {
//uploadProgress
....
},function( file,response ) {
//uploadSuccess
....
},function( file,reason ) {
//uploadError
....
},function( file,uploader ) {
//uploadComplete
....
}
);
后台代码,支持分片上传,秒传的问题在IE8下面要修改flash,不会玩,so不支持了吧。下面的代码不全,但是意思是对了,照着做肯定能出来。
@RequestMapping("/upload")
@ResponseBody
public String upload(@RequestParam("file") CommonsMultipartFile file, Integer chunks,
Integer chunk, HttpSession session) {
String path = null;
String fileName = file.getOriginalFilename();
String uploadTempDir = FileUtil.getSysConfig("uploadTempDir");
path = FileUtil.getUploadFileName(user.getUsername() + "/", fileName);
// 小文件直接上传
if (chunks == null) {
File newFile = new File(path);
file.transferTo(newFile);
// 大文件,分片(5M)上传
} else {
String tempDir = uploadTempDir + user.getUsername() + "/" + fileName;
File dir = FileUtil.createDir(tempDir);
File partFile = new File(tempDir + "/" + chunk + ".part");
file.transferTo(partFile);
// 上传完成
if (dir.listFiles().length == chunks) {
String[] files = new String[chunks];
;
for (int i = 0; i < chunks; i++) {
files[i] = tempDir + "/" + i + ".part";
}
// 合并
FileUtil.mergeFiles(path, files);
// 删除临时文件夹
FileUtil.delDir(tempDir);
} else {
return null;
}
}
}
一些踩过的坑,以下是ie8下面使用flash上传的时候遇到的问题:
一、点击上传按钮没有反应:
1、检查flash文件路径是否正确
2、上面封装的HDUpload init方法中的参数不需要的话,一定传null过去,比如accept千万别传{}过去
二、上传明明成功了,但是页面老是走uploadError方法:
因为文件上传处理后需要返回一些操作结果到页面,那么一开始后台的upload方法返回时并不是String而是写成了Map,因为可以自动转json嘛,但是就出现了上面的问题。
只需要将返回值改成String就好了,json可以用jackson之类的工具转一下。
三、明明上传路径是正确的,但是就是报400:
后台upload方法,参数名不能有id,换个名字就好了。
然后就可以愉快的玩耍了。
总结:
1、因为Web Uploader并不涉及UI,so前端的编写非常自由。
2、上传进度不用写后台,非常方便。
3、分片并发上传、秒传,支持更大文件,效率高、用户体验好。
学习建议:
http://fex.baidu.com/webuploader/getting-started.html
照着这个写个例子
http://fex.baidu.com/webuploader/doc/index.html
API从头看到尾,你就明白了