vue-simple-uploader 文件上传 分片上传 [直接上手]
vue-simple-uploader 文件上传 分片上传 [直接上手]
大家阅读前请最好阅读一下官方文档,了解一下各个参数的作用。
好了,话不多说,上码!
一、前端
1.安装:npm install vue-simple-uploader --save
2.使用:在main.js中
3.创建一个上传页面,我这里假定为uploadFile.vue了
<template> <div> <interviewBack /> <div> <uploader :options="options" :file-status-text="statusText" class="uploader-example" ref="uploader" @file-success="fileSuccess" style="width: 100%;" > <uploader-unsupport></uploader-unsupport> <uploader-drop> <p>欢迎来到上传录音界面</p> <uploader-btn>选择录音</uploader-btn> </uploader-drop> <uploader-list></uploader-list> </uploader> </div> </div> </template> <script> import interviewBack from '@/views/interview/interviewBack' export default { data() { return { recording: {}, options: { // https://github.com/simple-uploader/Uploader/tree/develop/samples/Node.js target: "http://10.31.37.2:8080/upload/upload", testChunks: false, //不校验 chunkSize: '10240000' }, statusText: { success: "上传成功", error: "上传失败", uploading: "上传中", paused: "暂停中", waiting: "等待中" } }; }, components:{ interviewBack }, methods: { //上传成功的事件 fileSuccess(rootFile, file, message, chunk) { console.log(message); //将面试邀请code和文件路径去保存到数据库中 var href = location.href; var split = href.split("?"); var invCode = split[1]; this.recording.invCode = invCode; this.recording.recordingUrl = message; // this.$ajax // .post( // "http://localhost:8080/interview/recording/saveFileData", // JSON.stringify(this.recording), // { // headers: { // "Content-Type": "application/json;charset=UTF-8" // } // } // ) // .then(response => { // if ("ok" == response.data) { // console.log("上传成功"); // } else { // alert("上传失败"); // } // }) // .catch(function(error) { // alert("上传失败"); // console.log(error); // }); } }, mounted() { // 获取uploader对象 this.$nextTick(() => { window.uploader = this.$refs.uploader.uploader; }); } }; </script> <style> .uploader-example { width: 100%; padding: 15px; margin: 50px auto 0; font-size: 12px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.4); } .uploader-example .uploader-btn { margin-right: 4px; } .uploader-example .uploader-list { max-height: 440px; overflow: auto; overflow-x: hidden; overflow-y: auto; } </style>
二、后端
1.控制层controller
1 package org.btz.ic.controller; 2 3 import java.io.PrintWriter; 4 5 import javax.annotation.Resource; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 9 import org.btz.ic.serviceImpl.UploadService; 10 import org.btz.ic.utils.UploadUtils; 11 import org.btz.ic.utils.Uploader; 12 import org.springframework.stereotype.Controller; 13 import org.springframework.web.bind.annotation.CrossOrigin; 14 import org.springframework.web.bind.annotation.RequestMapping; 15 import org.springframework.web.bind.annotation.RequestMethod; 16 import org.springframework.web.bind.annotation.ResponseBody; 17 /** 18 * 19 * @author haoze 20 * 21 */ 22 @CrossOrigin 23 @Controller 24 @RequestMapping("/upload") 25 public class UoloadController { 26 27 @Resource 28 private UploadService uploadService; 29 30 @ResponseBody 31 @RequestMapping(path = "/upload2", method = RequestMethod.POST) 32 public void upload(HttpServletRequest request, HttpServletResponse response){ 33 new UploadUtils().upload(request); 34 this.success(response, "上传成功!"); 35 } 36 37 38 public void success(HttpServletResponse response, Object obj){ 39 PrintWriter writer = null; 40 try { 41 writer = response.getWriter(); 42 writer.write(obj.toString()); 43 } catch(Exception e){} finally{ 44 if( writer != null ){ 45 //writer.close(); 46 } 47 } 48 } 49 50 /** 51 * 分片上传 52 * @param request 前台发送过来的文件内容 53 * @param response 响应给前台文件路径 54 * @throws Exception 55 */ 56 @RequestMapping(value = "/upload", method = RequestMethod.POST) 57 public void upload2(HttpServletRequest request, HttpServletResponse response) throws Exception{ 58 final String[] filepath = {""}; 59 final String[] or_filename = {""}; 60 try{ 61 uploadService.post(request, new Uploader.UploadListener() { 62 @Override 63 public void callback(String status, String filename, String original_filename, String identifier, String fileType) { 64 if(status != null){ 65 System.out.println(filename); 66 } 67 filepath[0] =filename;//文件上传的路径带走 68 or_filename[0] =original_filename;//源文件名称带走 69 } 70 }); 71 }catch(Exception e){ 72 e.printStackTrace(); 73 } 74 //这句话的意思,是让浏览器用utf8来解析返回的数据 75 response.setHeader("Content-type", "text/html;charset=UTF-8"); 76 //这句话的意思,是告诉servlet用UTF-8转码,而不是用默认的ISO8859 77 response.setCharacterEncoding("UTF-8"); 78 response.getWriter().append(filepath[0]+"---"+ or_filename[0]); 79 } 80 81 // @RequestMapping("/saveFileData") 82 // public String saveFileData(@RequestBody Recording recording){ 83 // try { 84 // recordingService.saveFileData(recording); 85 // return "ok"; 86 // } catch (Exception e) { 87 // return "no"; 88 // } 89 // } 90 91 }
2.service 类 代码内路径为存储上传文件的地址
1 package org.btz.ic.serviceImpl; 2 3 import org.btz.ic.utils.Uploader; 4 import org.springframework.stereotype.Service; 5 6 @Service 7 public class UploadService extends Uploader{ 8 public UploadService(){ 9 super("F:/tmp/","file"); 10 } 11 }
3.上一个工具类吧哈哈哈
1 package org.btz.ic.utils; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.util.Iterator; 6 7 import javax.servlet.http.HttpServletRequest; 8 9 import org.springframework.web.multipart.MultipartFile; 10 import org.springframework.web.multipart.MultipartHttpServletRequest; 11 import org.springframework.web.multipart.commons.CommonsMultipartResolver; 12 13 public class UploadUtils { 14 15 public String upload(HttpServletRequest request) { 16 String path = "F:/tmp/"; 17 CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver( 18 request.getSession().getServletContext()); 19 if (multipartResolver.isMultipart(request)) { 20 MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request; 21 Iterator<String> iter = multiRequest.getFileNames(); 22 while (iter.hasNext()) { 23 // 一次遍历所有文件 24 MultipartFile file = multiRequest.getFile(iter.next().toString()); 25 if (file != null) { 26 String p = path + "/" + file.getOriginalFilename(); 27 // 上传 28 try { 29 file.transferTo(new File(p)); 30 return p; 31 } catch (IllegalStateException e) { 32 e.printStackTrace(); 33 } catch (IOException e) { 34 e.printStackTrace(); 35 } 36 } 37 } 38 } 39 return null; 40 } 41 }
1 package org.btz.ic.utils;//Uploader.java 2 3 4 import org.apache.commons.io.FilenameUtils; 5 import org.springframework.web.multipart.MultipartFile; 6 import org.springframework.web.multipart.MultipartHttpServletRequest; 7 import org.springframework.web.multipart.commons.CommonsMultipartResolver; 8 9 import javax.servlet.http.HttpServletRequest; 10 import java.io.*; 11 import java.util.Iterator; 12 13 //https://github.com/simple-uploader/Uploader/blob/develop/samples/Node.js/uploader-node.js 14 /** 15 * 断点续传 16 * 17 * @author jwj 18 * 19 */ 20 public class Uploader { 21 /** 22 * 临时文件夹 23 */ 24 private String temporaryFolder; 25 /** 26 * 最大文件大小 27 */ 28 private Integer maxFileSize = 524288000; 29 // private String fileParameterName; 30 31 public Uploader(String temporaryFolder, String fileParameterName) { 32 this.temporaryFolder = temporaryFolder; 33 File file = new File(temporaryFolder); 34 if (!file.exists()) { 35 file.mkdirs(); 36 } 37 // if (fileParameterName == null) { 38 // this.fileParameterName = "file"; 39 // } else { 40 // this.fileParameterName = fileParameterName; 41 // } 42 } 43 44 public String cleanIdentifier(String identifier) { 45 return identifier.replaceAll("[^0-9A-Za-z_-]", ""); 46 } 47 48 public String getChunkFilename(int chunkNumber, String identifier) { 49 identifier = cleanIdentifier(identifier); 50 return new File(temporaryFolder, "jwj-" + identifier + '-' + chunkNumber).getAbsolutePath(); 51 } 52 53 public String validateRequest(int chunkNumber, int chunkSize, int totalSize, String identifier, String filename, 54 Integer fileSize) { 55 identifier = cleanIdentifier(identifier); 56 57 if (chunkNumber == 0 || chunkSize == 0 || totalSize == 0 || identifier.length() == 0 58 || filename.length() == 0) { 59 return "non_uploader_request"; 60 } 61 int numberOfChunks = (int) Math.max(Math.floor(totalSize / (chunkSize * 1.0)), 1); 62 if (chunkNumber > numberOfChunks) { 63 return "invalid_uploader_request1"; 64 } 65 66 if (this.maxFileSize != null && totalSize > this.maxFileSize) { 67 return "invalid_uploader_request2"; 68 } 69 70 if (fileSize != null) { 71 if (chunkNumber < numberOfChunks && fileSize != chunkSize) { 72 return "invalid_uploader_request3"; 73 } 74 if (numberOfChunks > 1 && chunkNumber == numberOfChunks 75 && fileSize != ((totalSize % chunkSize) + chunkSize)) { 76 return "invalid_uploader_request4"; 77 } 78 if (numberOfChunks == 1 && fileSize != totalSize) { 79 return "invalid_uploader_request5"; 80 } 81 } 82 83 return "valid"; 84 } 85 86 public int getParamInt(HttpServletRequest req, String key, int def) { 87 String value = req.getParameter(key); 88 try { 89 return Integer.parseInt(value); 90 } catch (Exception e) { 91 } 92 return def; 93 } 94 95 public String getParamString(HttpServletRequest req, String key, String def) { 96 String value = req.getParameter(key); 97 try { 98 return value == null ? def : value; 99 } catch (Exception e) { 100 } 101 return def; 102 } 103 104 public void get(HttpServletRequest req, UploadListener listener) { 105 int chunkNumber = this.getParamInt(req, "chunkNumber", 0); 106 int chunkSize = this.getParamInt(req, "chunkSize", 0); 107 int totalSize = this.getParamInt(req, "totalSize", 0); 108 String identifier = this.getParamString(req, "identifier", ""); 109 String filename = this.getParamString(req, "filename", ""); 110 if (validateRequest(chunkNumber, chunkSize, totalSize, identifier, filename, null).equals("valid")) { 111 String chunkFilename = getChunkFilename(chunkNumber, identifier); 112 if (new File(chunkFilename).exists()) { 113 listener.callback("found", chunkFilename, filename, identifier, null); 114 } else { 115 listener.callback("not_found", null, null, null, null); 116 } 117 118 } else { 119 listener.callback("not_found", null, null, null, null); 120 } 121 } 122 123 public void post(HttpServletRequest req, UploadListener listener) throws IllegalStateException, IOException { 124 125 int chunkNumber = this.getParamInt(req, "chunkNumber", 0); 126 int chunkSize = this.getParamInt(req, "chunkSize", 0); 127 int totalSize = this.getParamInt(req, "totalSize", 0); 128 String identifier = this.getParamString(req, "identifier", ""); 129 String filename = this.getParamString(req, "filename", ""); 130 131 CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(req.getSession().getServletContext()); 132 133 if (multipartResolver.isMultipart(req)) { 134 // 将request变成多部分request 135 MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) req; 136 // 获取multiRequest 中所有的文件名 137 Iterator<String> iter = multiRequest.getFileNames(); 138 while (iter.hasNext()) { 139 String name = iter.next().toString(); 140 // if (!this.fileParameterName.equals(name)) { 141 // continue; 142 // } 143 MultipartFile file = multiRequest.getFile(name); 144 145 if (file != null && file.getSize() > 0) { 146 String original_filename = file.getOriginalFilename(); 147 // String original_filename = 148 // files[this.fileParameterName]['originalFilename']; 149 String validation = validateRequest(chunkNumber, chunkSize, totalSize, identifier, filename, 150 (int) file.getSize()); 151 152 if ("valid".equals(validation)) { 153 String chunkFilename = getChunkFilename(chunkNumber, identifier); 154 155 File f = new File(chunkFilename); 156 if (!f.exists()) { 157 file.transferTo(f); 158 } 159 160 int currentTestChunk = 1; 161 int numberOfChunks = (int) Math.max(Math.floor(totalSize / (chunkSize * 1.0)), 1); 162 163 currentTestChunk = this.testChunkExists(currentTestChunk, chunkNumber, numberOfChunks, 164 chunkFilename, original_filename, identifier, listener,"file"); 165 166 } else { 167 listener.callback(validation, filename, original_filename, identifier,"file"); 168 } 169 } else { 170 listener.callback("invalid_uploader_request", null, null, null, null); 171 } 172 } 173 } 174 } 175 176 private void pipeChunk(int number, String identifier, UploadOptions options, OutputStream writableStream) 177 throws IOException { 178 String chunkFilename = getChunkFilename(number, identifier); 179 if (new File(chunkFilename).exists()) { 180 FileInputStream inputStream = new FileInputStream(new File(chunkFilename)); 181 int maxlen = 1024; 182 int len = 0; 183 try { 184 byte[] buff = new byte[maxlen]; 185 while ((len = inputStream.read(buff, 0, maxlen)) > 0) { 186 writableStream.write(buff, 0, len); 187 } 188 } finally { 189 inputStream.close(); 190 } 191 pipeChunk(number + 1, identifier, options, writableStream); 192 } else { 193 if (options.end) 194 writableStream.close(); 195 if (options.listener != null) 196 options.listener.onDone(); 197 } 198 } 199 200 public void write(String identifier, OutputStream writableStream, UploadOptions options) throws IOException { 201 if (options == null) { 202 options = new UploadOptions(); 203 } 204 if (options.end == null) { 205 options.end = true; 206 } 207 pipeChunk(1, identifier, options, writableStream); 208 } 209 210 /** 211 * 212 * @param currentTestChunk 213 * @param chunkNumber 当前上传块 214 * @param numberOfChunks 总块数 215 * @param filename 文件名称 216 * @param original_filename 源文件名称 217 * @param identifier 文件 218 * @param listener 监听 219 * @param fileType 220 * @return 221 */ 222 private int testChunkExists(int currentTestChunk, int chunkNumber, int numberOfChunks, String filename, 223 String original_filename, String identifier, UploadListener listener, String fileType) { 224 String cfile = getChunkFilename(currentTestChunk, identifier); 225 if (new File(cfile).exists()) { 226 currentTestChunk++; 227 if (currentTestChunk >= chunkNumber) { 228 if (chunkNumber == numberOfChunks) { 229 try { 230 System.out.println("done"); 231 // 文件合并 232 UploadOptions options = new UploadOptions(); 233 File f = new File(this.temporaryFolder, 234 original_filename.substring(0,original_filename.lastIndexOf("."))+"-"+UuidUtils.uuid()+"." + FilenameUtils.getExtension(original_filename)); 235 options.listener = new UploadDoneListener() { 236 @Override 237 public void onError(Exception err) { 238 listener.callback("invalid_uploader_request", f.getAbsolutePath(), original_filename, 239 identifier, fileType); 240 clean(identifier, null); 241 } 242 243 @Override 244 public void onDone() { 245 listener.callback("done", f.getAbsolutePath(), original_filename, identifier, fileType); 246 clean(identifier, null); 247 } 248 }; 249 this.write(identifier, new FileOutputStream(f), options); 250 } catch (FileNotFoundException e) { 251 e.printStackTrace(); 252 listener.callback("invalid_uploader_request", filename, original_filename, identifier, 253 fileType); 254 } catch (IOException e) { 255 e.printStackTrace(); 256 listener.callback("invalid_uploader_request", filename, original_filename, identifier, 257 fileType); 258 } 259 } else { 260 listener.callback("partly_done", filename, original_filename, identifier, fileType); 261 } 262 } else { 263 return testChunkExists(currentTestChunk, chunkNumber, numberOfChunks, filename, original_filename, 264 identifier, listener, fileType); 265 } 266 } else { 267 listener.callback("partly_done", filename, original_filename, identifier, fileType); 268 } 269 return currentTestChunk; 270 } 271 272 public void clean(String identifier, UploadOptions options) { 273 if (options == null) { 274 options = new UploadOptions(); 275 } 276 pipeChunkRm(1, identifier, options); 277 } 278 279 private void pipeChunkRm(int number, String identifier, UploadOptions options) { 280 281 String chunkFilename = getChunkFilename(number, identifier); 282 File file = new File(chunkFilename); 283 if (file.exists()) { 284 try { 285 file.delete(); 286 } catch (Exception e) { 287 if (options.listener != null) { 288 options.listener.onError(e); 289 } 290 } 291 pipeChunkRm(number + 1, identifier, options); 292 293 } else { 294 if (options.listener != null) 295 options.listener.onDone(); 296 } 297 } 298 299 public static interface UploadListener { 300 public void callback(String status, String filename, String original_filename, String identifier, 301 String fileType); 302 } 303 304 public static interface UploadDoneListener { 305 public void onDone(); 306 307 public void onError(Exception err); 308 } 309 310 public static class UploadOptions { 311 public Boolean end; 312 public UploadDoneListener listener; 313 } 314 }
三、至此就差不多了
但是呢 可能会出现一些小问题 例如文件大小的问题 那么这时候就需要这么一个配置了
这是spring下的配置,自行添加,经god测试,最大上传文件为1GB大小 超出则报错
效果图如下:
对你有用的话请点赞!评论加关注,感谢您的观看!
联系QQ:3418187513