webuploader分片上传的实现代码(前后端分离)
程序员文章站
2022-04-10 20:19:53
本文介绍了webuploader分片上传的实现代码(前后端分离),分享给大家,具体如下:
webuploader是由baidu webfe(fex)团队开发的一个简单的以...
本文介绍了webuploader分片上传的实现代码(前后端分离),分享给大家,具体如下:
webuploader是由baidu webfe(fex)团队开发的一个简单的以html5为主,flash为辅的现代文件上传组件。在现代的浏览器里面能充分发挥html5的优势,同时又不摒弃主流ie浏览器,沿用原来的flash运行时,兼容ie6+,ios 6+, android 4+。两套运行时,同样的调用方式,可供用户任意选用。采用大文件分片并发上传,极大的提高了文件上传效率。(这个是从官网上直接copy的解释)
功能描述
1、webuploader是百度研发的上传组件,文档不是特别规整,但是也够用了。
2、前端使用官网的上传图片demo,在此基础上代码略微调整做分片。既可以上传图片也可以上传文件。文件超过分片大小才启用分片。
3、分片上传已做md5校验,达到秒传的效果。分片以后需要合并,可以先分片后合并,也可以边分片边合并,本示例采用的是边分片边合并的方案。
4、后端用springboot做框架搭建。springmvc做rest服务,开启跨域访问。
5、容器用springboot内置的tomcat插件,运行application的main方法即可启动服务;
显示效果
关键代码前端
webuploader.uploader.register({ 'name': 'webuploaderhookcommand', 'before-send-file': 'beforesendfile', "before-send": "beforesend" }, { beforesendfile: function(file) { var task = new webuploader.deferred(); filename = file.name; filesize = file.size; (new webuploader.uploader()).md5file(file, 0, 10 * 1024 * 1024).progress(function(percentage) {}).then(function(val) { filemd5 = val; var url = checkurl; var data = { type: 0, filename: filename, filemd5: filemd5, filesize: filesize }; $.ajax({ type: "post", url: url, data: data, cache: false, async: false, // 同步 timeout: 1000, // todo 超时的话,只能认为该分片未上传过 datatype: "json", error: function(xmlhttprequest, textstatus, errorthrown) { file.statustext = 'server_error'; task.reject(); } }).then(function(data, textstatus, jqxhr) { if(data.rtn == 0) { if(data.obj == 1) { file.statustext = 'file_existed'; task.reject(); } else { task.resolve(); } } else { task.reject(); } }); }); return task.promise(); }, beforesend: function(block) { var task = new webuploader.deferred(); var url = checkurl; var data = { type: 1, filename: filename, filemd5: filemd5, chunk: block.chunk, filesize: block.end - block.start }; $.ajax({ type: "post", url: url, data: data, cache: false, async: false, // 同步 timeout: 1000, // todo 超时的话,只能认为该分片未上传过 datatype: "json" }).then(function(data, textstatus, jqxhr) { if(data.rtn == 0 && data.obj == 1) { task.reject(); // 分片存在,则跳过上传 } else { task.resolve(); } }); this.owner.options.formdata.filemd5 = filemd5; this.owner.options.formdata.chunksize = chunksize; return task.promise(); } }); // 实例化 uploader = webuploader.create({ pick: { id: '#filepicker', label: '点击选择文件' }, formdata: { uid: 123 }, dnd: '#dndarea', //指定文件拖拽的区域 paste: '#uploader', //指定监听paste事件的容器,如果不指定,不启用此功能。此功能为通过粘贴来添加截屏的图片。建议设置为document.body. swf: '../plugins/webuploader/uploader.swf', chunked: true, chunksize: chunksize, chunkretry: false, threads: 1, server: uploadurl, // runtimeorder: 'flash', // accept: { // title: 'images', // extensions: 'gif,jpg,jpeg,bmp,png', // mimetypes: 'image/*' // }, // 禁掉全局的拖拽功能。这样不会出现图片拖进页面的时候,把图片打开。 disableglobaldnd: true, filenumlimit: 300 //限制多文件上传的个数 //filesizelimit: 200 * 1024 * 1024, // 限制所有文件的大小 200 m //filesinglesizelimit: 50 * 1024 * 1024 // 限制单个文件的大小 50 m });
后端
import java.io.file; import java.io.ioexception; import org.slf4j.logger; import org.slf4j.loggerfactory; import org.springframework.beans.factory.annotation.value; import org.springframework.stereotype.service; import org.springframework.web.multipart.multipartfile; import com.bear.upload.util.fileutil; import com.bear.upload.util.return; import com.bear.upload.vo.checkmd5filevo; import com.bear.upload.vo.uploadvo; @service public class chunkuploadservice { private static logger log = loggerfactory.getlogger(chunkuploadservice.class); @value("${file.upload.path}") private string upload_path; private static final string delimiter = "-"; /** * 上传之前校验(整个文件、分片) * * @param md5filevo * @return */ public object check(checkmd5filevo md5filevo) { integer type = md5filevo.gettype(); long chunk = md5filevo.getchunk(); string filename = md5filevo.getfilename(); long filesize = md5filevo.getfilesize(); if (type == 0) {// 未分片校验 string destfilepath = upload_path + file.separator + filename; file destfile = new file(destfilepath); if (destfile.exists() && destfile.length() == filesize) { return return.success("文件已存在,跳过", 1); } else { return return.success("文件不存在", 0); } } else {// 分片校验 string filemd5 = md5filevo.getfilemd5(); string destfiledir = upload_path + file.separator + filemd5; string destfilename = chunk + delimiter + filename; string destfilepath = destfiledir + file.separator + destfilename; file destfile = new file(destfilepath); if (destfile.exists() && destfile.length() == filesize) { return return.success("分片已存在,跳过", 1); } else { return return.success("分片不存在", 0); } } } /** * 文件上传 * * @param file * @param uploadvo * @param appversion * @return */ public object upload(multipartfile file, uploadvo uploadvo) { long chunk = uploadvo.getchunk(); if (chunk == null) {// 没有分片 return unchunkupload(file, uploadvo); } else {// 分片 return chunkupload(file, uploadvo); } } /** * 分片上传 * * @param file * @param uploadvo * @param appversion * @return */ public object chunkupload(multipartfile file, uploadvo uploadvo) { string filename = uploadvo.getname(); string filemd5 = uploadvo.getfilemd5(); long chunk = uploadvo.getchunk();// 当前片 long chunks = uploadvo.getchunks();// 总共多少片 // 分片目录创建 string chunkdirpath = upload_path + file.separator + filemd5; file chunkdir = new file(chunkdirpath); if (!chunkdir.exists()) { chunkdir.mkdirs(); } // 分片文件上传 string chunkfilename = chunk + delimiter + filename; string chunkfilepath = chunkdir + file.separator + chunkfilename; file chunkfile = new file(chunkfilepath); try { file.transferto(chunkfile); } catch (exception e) { log.error("分片上传出错", e); return return.fail("分片上传出错", 1); } // 合并分片 long chunksize = uploadvo.getchunksize(); long seek = chunksize * chunk; string destfilepath = upload_path + file.separator + filename; file destfile = new file(destfilepath); if (chunkfile.length() > 0) { try { fileutil.randomaccessfile(chunkfile, destfile, seek); } catch (ioexception e) { log.error("分片{}合并失败:{}", chunkfile.getname(), e.getmessage()); return return.fail("分片合并失败", 1); } } if (chunk == chunks - 1) { // 删除分片文件夹 fileutil.deletedirectory(chunkdirpath); return return.success("上传成功", 1); } else { return return.fail("上传中...", 1); } } /** * 未分片上传 * * @param file * @param uploadvo * @param appversion * @return */ public object unchunkupload(multipartfile file, uploadvo uploadvo) { string filename = uploadvo.getname(); // string filemd5 = uploadvo.getfilemd5(); // 文件上传 file destfile = new file(upload_path + file.separator + filename); if (file != null && !file.isempty()) { // 上传目录 file filedir = new file(upload_path); if (!filedir.exists()) { filedir.mkdirs(); } if (destfile.exists()) { destfile.delete(); } try { file.transferto(destfile); return return.success("上传成功", 0); } catch (exception e) { log.error("文件上传出错", e); return return.fail("文件上传出错", 0); } } return return.fail("上传失败", 0); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读