webuploader分片上传(前后端分离)

来源:互联网 发布:win10 grub引导ubuntu 编辑:程序博客网 时间:2024/06/06 08:31

功能描述

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;@Servicepublic 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);}}

需要完整代码加QQ群,有问题参与讨论:616697860  


原创粉丝点击