webupload分片上传
参考博客:https://blog.csdn.net/niugang0920/article/details/89387209
js代码:
mini.parse(); function webUploader(e, type) { var serverUrl; var typeError; var KjURL = '/tst-api/kjfile/upload';//重点文件上传路径 var ImgURL = '/tst-api/file/horizontalThumbnailUpload'; var fileArray = []; var accept; var chunkSize; var $list; var $notChoose; var size; if (type == 'file') { serverUrl = KjURL; $list = $('#fstatus'); $notChoose = $('#fdiv'); chunkSize = 1 * 1024 * 1024; size= 500 ; typeError = '只能上传带有内容的word,pdf和mp4,wmv,mov,flv,avi,3gp,mkv格式的视频文件'; accept = {//格式校验 title: 'file', extensions: 'pdf,doc,docx,mp4,wmv,mkv,mov,flv,avi,3gp', mimeTypes: //word 'file/*' } } else if (type == 'img') { serverUrl = ImgURL; $list = $('#hstatus'); $notChoose = $('#hdiv'); typeError = '只能上传图片'; chunkSize = 5 * 1024 * 1024; accept = { title: 'Images', extensions: 'gif,jpg,jpeg,bmp,png', mimeTypes: 'image/*' } } var uploader = WebUploader.create({ // alert(e), // 文件接收服务端。 server: serverUrl, // 选择文件的按钮。可选。 // 内部根据当前运行是创建,可能是input元素,也可能是flash. pick: { id: '#' + e, multiple: false }, //是否自动上传 auto: true, fileSingleSizeLimit:size * 1024 * 1024, fileVal: 'tfile', // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传! resize: false, duplicate: true, chunked: true, threads: 5, chunkSize: chunkSize, accept: accept }); //点击上传之前调用的方法 uploader.on("uploadStart", function (file) { var guid = WebUploader.Base.guid(); uploader.options.formData.guid = guid; fileArray.push({ "guid": guid, "filedId": file.source.ruid }); $notChoose.hide(); if (type == "file") { mini.get("fid").setValue(''); } else if (type == "img") { mini.get("slth").setValue(''); } }); // 当有文件被添加进队列的时候 uploader.on('fileQueued', function (file) { $list.html(''); $list.append('<div id="' + file.id + '" class="item">' + '<h4 class="info">' + file.name + '</h4>' + '<p class="state"></p>' + '</div>'); }); // 文件上传过程中创建进度条实时显示。 uploader.on('uploadProgress', function (file, percentage) { var $li = $('#' + file.id), $percent = $li.find('.progress .progress-bar'); // 避免重复创建 if (!$percent.length) { $percent = $('<div class="progress progress-striped active">' + '<div class="progress-bar" role="progressbar" style="width: 0%">' + '</div>' + '</div>').appendTo($li).find('.progress-bar'); } $li.find('p.state').text('上传中:'+percentage.toFixed(2) * 100 + '%'); $percent.css('width', percentage * 100 + '%'); }); // 验证文件格式以及文件大小 uploader.on('error', function (code, file) { var str = ""; switch (code) { case "Q_TYPE_DENIED": alert(typeError); break; case "F_EXCEED_SIZE": alert("文件大小不能超过"+size+"M"); break; case "Q_EXCEED_SIZE_LIMIT": alert("超出空间文件大小"); break; default: alert("上传出错!请检查后重新上传!错误代码" + code); } }); //文件成功、失败处理 uploader.on('uploadSuccess', function (file, response) { var successFileId = file.source.ruid; var successDuid; if (fileArray.length > 0) { for (var i = 0; i < fileArray.length; i++) { if (fileArray[i].filedId === successFileId) { successDuid=fileArray[i].guid; fileArray.splice(i, 1); } } } $.get("/tst-api/kjfile/merge", {"guid": successDuid}, function (data, status) { console.log(data); if (data.code == '0') { var result = data.obj; if (type == "file") { var html = '<a style="width:270px;display:inline-block;overflow: hidden;text-overflow:ellipsis;white-space: nowrap;" title="' + result.filename + '" href="javascript:show4(\'' + result.id + '\',\'' + result.contenttype + '\')">' + result.filename + '</a>'; $list.find('h4.info').html(html); $("#fdiv").hide(); mini.get("fid").setValue(result.id); } else if (type == "img") { $list.find('h4.info').html( '<a style="width:270px;display:inline-block;overflow: hidden;text-overflow:ellipsis;white-space: nowrap;" title="' + result.filename + '" href="javascript:yulan(\'' + result.id + '\',\'h\')">' + result.filename + '</a>' ); $("#hdiv").hide(); mini.get("slth").setValue(result.id); } $( '#'+file.id ).find('p.state').text('已上传'); }else{ $( '#'+file.id ).find('p.state').text('上传失败'); } }); }); //文件上传出错 uploader.on('uploadError', function (file) { $('#' + file.id).find('p.state').text('上传出错'); }); //文件上传完成 uploader.on('uploadComplete', function (file) { $( '#'+file.id ).find('.progress').fadeOut(); $("") }); }
2后台主要有两部分一是文件上传路径(后台接收分片文件)二是将分片后的文件合并
package ax.tst.web.controller; import ax.f4j.file.FileStore; import ax.f4j.model.JsonResult; import ax.f4j.model.ResultUtil; import ax.tst.common.AuthTools; import ax.tst.common.UserInfo; import ax.tst.entity.ResFile; import ax.tst.exception.TstCommonException; import ax.tst.service.FileServiceI; import ax.tst.service.OrgServiceI; import io.swagger.annotations.Api; import org.apache.commons.io.FileUtils; import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.Date; /** * @author Created by niugang on 2019/1/24/11:42 */ @SuppressWarnings("ResultOfMethodCallIgnored") @CrossOrigin @RestController @RequestMapping("/kjfile") @Api(value = "/kjfile", tags = {"1.文件相关"}) public class KjFileController { @Autowired ax.tst.common.util.ConverVideoUtils ConverVideoUtils; @Autowired private FileStore fileStore; @Autowired private FileServiceI fileService; @Autowired private AuthTools authTools; @Autowired private OrgServiceI orgServiceI; @Value("${f4j.file-copy-file-store-root}") private String FILEPATH;//文件存放源目录 @Value("${kjVideoConfig.video-format}") private String targetExtension;//转码格式 private static String ContentType = "";//文件类型 private static String OriginalFilename="";//上传文件名 private static String fileSuffixName;// //文件后缀格式 private ResFile resFile=new ResFile(); private static String fileUrlTemp;//临时目录 private static String Relativeaddress;//文件上传相对地址 private String fileUrl;//文件上传绝对地址 @GetMapping("/") public String index() { return "index"; } @GetMapping("/webuploader") public String webuploader() { return "webupload"; } @GetMapping("downloaderror") public String downloaderror() { return "error"; } /** * 分片上传 * * @return ResponseEntity<Void> */ @PostMapping("/upload") @ResponseBody public JsonResult decrypt(HttpServletRequest request, @RequestParam(value = "tfile", required = false) MultipartFile file, Integer chunks, Integer chunk, String name, String guid) throws IOException { boolean isMultipart = ServletFileUpload.isMultipartContent(request); UserInfo userInfo = authTools.getUserInfo(); //必须登录 userInfo.checkLogin(); //必须有资源维护权限 if (isMultipart) { if (file == null) { throw new TstCommonException("文件上传出错!"); } System.out.println("guid:" + guid); if (chunks == null && chunk == null) { chunk = 0; } OriginalFilename=file.getOriginalFilename();//获取文件的名称 //上传年月 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM"); String date = sdf.format(new Date()); fileSuffixName =OriginalFilename.substring(OriginalFilename.lastIndexOf("."));//文件后缀格式 fileUrlTemp =FILEPATH+"file/" + orgServiceI.findUploadOrgCodeByOrgid(userInfo.getOrgid()) + "/" + date + "/temp/";//临时目录 Relativeaddress="file/"+orgServiceI.findUploadOrgCodeByOrgid(userInfo.getOrgid()) + "/" + date + "/"; fileUrl=FILEPATH+ Relativeaddress;//文件存放地址 resFile=new ResFile(); if (fileSuffixName.equals(".doc") || fileSuffixName.equals(".docx")) { ContentType = "application/pdf"; } File outFile = new File(fileUrlTemp+File.separator+guid, chunk + ".part"); InputStream inputStream = file.getInputStream(); FileUtils.copyInputStreamToFile(inputStream, outFile); } return ResultUtil.success("ok"); } /** * 合并所有分片 * * @throws Exception Exception */ @GetMapping("/merge") @ResponseBody public JsonResult byteMergeAll(String guid) throws Exception { System.out.println("merge:"+guid); UserInfo userInfo = authTools.getUserInfo(); resFile.setFilename(OriginalFilename); resFile.setUploadUser(userInfo.getName()); resFile.setUploadTime(new Date()); try { fileService.save(resFile);//保存文件上传记录 String Final_FILENAME=resFile.getId() + fileSuffixName;//以上传记录的id给上传文件赋名 File file = new File(fileUrlTemp+File.separator+guid); if (file.isDirectory()) { File[] files = file.listFiles(); if (files != null && files.length > 0) { File partFile = new File(fileUrl + File.separator + Final_FILENAME); for (int i = 0; i < files.length; i++) { File s = new File(fileUrlTemp+File.separator+guid, i + ".part"); FileOutputStream destTempfos = new FileOutputStream(partFile, true); FileUtils.copyFile(s,destTempfos ); destTempfos.close(); } File tempFile = new File(fileUrlTemp+"/"+guid+"/"); delFile(tempFile);//删除临时文件 if (fileSuffixName.equals(".doc") || fileSuffixName.equals(".docx")) { fileService.kjdoc2ToPdf(partFile, Relativeaddress + resFile.getId() + ".pdf", resFile.getId());//转成pdf ContentType = getContentType(fileUrl + Final_FILENAME); resFile.setContenttype(ContentType);//获取文件的ContentType resFile.setPath("/"+Relativeaddress+resFile.getId()+".pdf"); fileService.save(resFile);//保存文件地址 delFile(partFile);//删除临时文件 return ResultUtil.success(resFile); } //非MP4的视频文件进行视频转码 else if(!fileSuffixName.equals(".mp4") && ConverVideoUtils.checkContentType(fileUrl + Final_FILENAME)==0){ String url = ConverVideoUtils.beginConver(fileUrl + Final_FILENAME, fileUrl, resFile.getId()); // delFile(partFile);//删除临时文件 ContentType = getContentType(url); resFile.setFilename(OriginalFilename); resFile.setContenttype("video/mp4");//获取文件的ContentType resFile.setPath("/"+Relativeaddress+resFile.getId()+targetExtension); fileService.save(resFile);//保存文件地址 return ResultUtil.success(resFile); } } ContentType = getContentType(fileUrl + Final_FILENAME); resFile.setContenttype(ContentType);//获取文件的ContentType resFile.setPath("/"+Relativeaddress+resFile.getId()+fileSuffixName); fileService.save(resFile);//保存文件地址 } } catch (Exception e) { e.printStackTrace(); return ResultUtil.error(4,e.getMessage()); } return ResultUtil.success(resFile); } /** * 获取文件的ContentType * 该方式支持本地文件,也支持http/https远程文件 * @param fileUrl */ public String getContentType(String fileUrl) { String contentType = null; if(ConverVideoUtils.checkContentType(fileUrl)==9){ contentType="application/pdf"; }else{ contentType="video/mp4"; } return contentType; } static void delFile(File file) { if(file.isFile()){ file.delete(); } if (file.isDirectory()) { File[] files = file.listFiles(); for (File f : files) { delFile(f); } } } public static void main(String[] args) { File tempFile = new File("D:/bzaq/file/00/2019-10/75dca877c2844fcea68e742f74491973.docx"); // System.out.println(fileUrlTemp+"/"+guid+"/"); if (tempFile.isFile() || tempFile.isDirectory()) { // boolean b = delFile(tempFile);//删除文件夹里面的文件 boolean delete = tempFile.delete(); System.out.println(delete); } } }