服务器之家

服务器之家 > 正文

vue-simple-uploader上传成功之后的response获取代码

时间:2021-09-17 13:20     来源/作者:BennyShi98

我就废话不多说了,大家还是直接看代码吧~

  1. <template>
  2. <uploader :options="options" :file-status-text="statusText" class="uploader-example" ref="uploader" @file-success="fileSuccess"></uploader>
  3. </template>
  4. <script>
  5. export default {
  6.  
  7. data () {
  8. return {
  9. options: {
  10. target: '//localhost:3000/upload', // '//jsonplaceholder.typicode.com/posts/',
  11. testChunks: false
  12. },
  13. attrs: {
  14. accept: 'image/*'
  15. },
  16. statusText: {
  17. success: '成功了',
  18. error: '出错了',
  19. uploading: '上传中',
  20. paused: '暂停中',
  21. waiting: '等待中'
  22. }
  23. }
  24. },
  25. methods: {
  26. //上传成功的事件
  27. fileSuccess (rootFile, file, message, chunk) {
  28. console.log('complete', rootFile, file, message, chunk)
  29. }
  30. },
  31. mounted () {
  32. // 获取uploader对象
  33. this.$nextTick(() => {
  34. window.uploader = this.$refs.uploader.uploader
  35. })
  36. }
  37. }
  38. </script>

补充知识:利用SpringBoot和vue-simple-uploader进行文件的分片上传

效果【上传Zip文件为例,可以自行扩展】

vue-simple-uploader上传成功之后的response获取代码

引入vue-simple-uploader

1.安装上传插件

npm install vue-simple-uploader --save

2.main.js全局引入上传插件

import uploader from 'vue-simple-uploader'

Vue.use(uploader)

3.安装md5校验插件(保证上传文件的完整性和一致性)

npm install spark-md5 --save

页面

  1. <template>
  2. <div>
  3. <uploader :key="uploader_key" :options="options" class="uploader-example"
  4. :autoStart="false"
  5. @file-success="onFileSuccess"
  6. @file-added="filesAdded">
  7. <uploader-unsupport></uploader-unsupport>
  8. <uploader-drop>
  9. <uploader-btn :single="true" :attrs="attrs">选择Zip文件</uploader-btn>
  10. </uploader-drop>
  11. <uploader-list></uploader-list>
  12. </uploader>
  13. </div>
  14. </template>
  15.  
  16. <script>
  17. import SparkMD5 from 'spark-md5';
  18.  
  19. export default {
  20. data() {
  21. return {
  22. uploader_key: new Date().getTime(),
  23. options: {
  24. target: '/chunk/chunkUpload',
  25. testChunks: false,
  26. },
  27. attrs: {
  28. accept: '.zip'
  29. }
  30. }
  31. },
  32. methods: {
  33. onFileSuccess: function (rootFile, file, response, chunk) {
  34. console.log(JSON.parse(response).model);
  35. },
  36. computeMD5(file) {
  37. const loading = this.$loading({
  38. lock: true,
  39. text: '正在计算MD5',
  40. spinner: 'el-icon-loading',
  41. background: 'rgba(0, 0, 0, 0.7)'
  42. });
  43. let fileReader = new FileReader();
  44. let time = new Date().getTime();
  45. let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
  46. let currentChunk = 0;
  47. const chunkSize = 10 * 1024 * 1000;
  48. let chunks = Math.ceil(file.size / chunkSize);
  49. let spark = new SparkMD5.ArrayBuffer();
  50. file.pause();
  51.  
  52. loadNext();
  53.  
  54. fileReader.onload = (e => {
  55. spark.append(e.target.result);
  56. if (currentChunk < chunks) {
  57. currentChunk++;
  58. loadNext();
  59. this.$nextTick(() => {
  60. console.log('校验MD5 ' + ((currentChunk / chunks) * 100).toFixed(0) + '%')
  61. })
  62. } else {
  63. let md5 = spark.end();
  64. loading.close();
  65. this.computeMD5Success(md5, file);
  66. console.log(`MD5计算完毕:${file.name} \nMD5${md5} \n分片:${chunks} 大小:${file.size} 用时:${new Date().getTime() - time} ms`);
  67. }
  68. });
  69. fileReader.onerror = function () {
  70. this.error(`文件${file.name}读取出错,请检查该文件`);
  71. loading.close();
  72. file.cancel();
  73. };
  74.  
  75. function loadNext() {
  76. let start = currentChunk * chunkSize;
  77. let end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;
  78. fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end));
  79. }
  80. },
  81. computeMD5Success(md5, file) {
  82. file.uniqueIdentifier = md5;//把md5值作为文件的识别码
  83. file.resume();//开始上传
  84. },
  85. filesAdded(file, event) {
  86. //大小判断
  87. const isLt100M = file.size / 1024 / 1024 < 10;
  88. if (!isLt100M) {
  89. this.$message.error(this.$t("error.error_upload_file_max"));
  90. } else {
  91. this.computeMD5(file)
  92. }
  93. }
  94. }
  95. }
  96. </script>
  97.  
  98. <style>
  99. .uploader-example {
  100. width: 90%;
  101. padding: 15px;
  102. margin: 40px auto 0;
  103. font-size: 12px;
  104. box-shadow: 0 0 10px rgba(0, 0, 0, .4);
  105. }
  106.  
  107. .uploader-example .uploader-btn {
  108. margin-right: 4px;
  109. }
  110.  
  111. .uploader-example .uploader-list {
  112. max-height: 440px;
  113. overflow: auto;
  114. overflow-x: hidden;
  115. overflow-y: auto;
  116. }
  117. </style>

后台

引入工具

  1. <dependency>
  2. <groupId>commons-io</groupId>
  3. <artifactId>commons-io</artifactId>
  4. <version>2.6</version>
  5. </dependency>
  6.  
  7. <dependency>
  8. <groupId>commons-lang</groupId>
  9. <artifactId>commons-lang</artifactId>
  10. <version>2.6</version>
  11. </dependency>

控制类

  1. import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
  2. import org.springframework.web.bind.annotation.RequestMapping;
  3. import org.springframework.web.bind.annotation.RestController;
  4.  
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. import java.io.File;
  8.  
  9. @RestController
  10. @RequestMapping("/chunk")
  11. public class ChunkController {
  12. @RequestMapping("/chunkUpload")
  13. public StdOut chunkUpload(MultipartFileParam param, HttpServletRequest request, HttpServletResponse response) {
  14. StdOut out = new StdOut();
  15.  
  16. File file = new File("C:\\chunk_test");//存储路径
  17.  
  18. ChunkService chunkService = new ChunkService();
  19.  
  20. String path = file.getAbsolutePath();
  21. response.setContentType("text/html;charset=UTF-8");
  22.  
  23. try {
  24. //判断前端Form表单格式是否支持文件上传
  25. boolean isMultipart = ServletFileUpload.isMultipartContent(request);
  26. if (!isMultipart) {
  27. out.setCode(StdOut.PARAMETER_NULL);
  28. out.setMessage("表单格式错误");
  29. return out;
  30. } else {
  31. param.setTaskId(param.getIdentifier());
  32. out.setModel(chunkService.chunkUploadByMappedByteBuffer(param, path));
  33. return out;
  34. }
  35. } catch (NotSameFileExpection e) {
  36. out.setCode(StdOut.FAIL);
  37. out.setMessage("MD5校验失败");
  38. return out;
  39. } catch (Exception e) {
  40. out.setCode(StdOut.FAIL);
  41. out.setMessage("上传失败");
  42. return out;
  43. }
  44. }
  45. }

StdOut类(只是封装的返回类)

  1. public class StdOut {
  2. public static final int SUCCESS = 200;
  3. public static final int FAIL = 400;
  4. public static final int PARAMETER_NULL = 500;
  5. public static final int NO_LOGIN = 600;
  6. private int code = 200;
  7. private Object model = null;
  8. private String message = null;
  9.  
  10. public StdOut() {
  11. this.setCode(200);
  12. this.setModel((Object)null);
  13. }
  14.  
  15. public StdOut(int code) {
  16. this.setCode(code);
  17. this.setModel((Object)null);
  18. }
  19.  
  20. public StdOut(List<Map<String, Object>> model) {
  21. this.setCode(200);
  22. this.setModel(model);
  23. }
  24.  
  25. public StdOut(int code, List<Map<String, Object>> model) {
  26. this.setCode(code);
  27. this.setModel(model);
  28. }
  29.  
  30. public int getCode() {
  31. return this.code;
  32. }
  33.  
  34. public void setCode(int code) {
  35. this.code = code;
  36. }
  37.  
  38. public String toString() {
  39. return JSON.toJSONString(this);
  40. }
  41.  
  42. public Object getModel() {
  43. return this.model;
  44. }
  45.  
  46. public void setModel(Object model) {
  47. this.model = model;
  48. }
  49.  
  50. public String getMessage() {
  51. return this.message;
  52. }
  53.  
  54. public void setMessage(String message) {
  55. this.message = message;
  56. }
  57. }

MultipartFileParam类(文件信息类)

  1. import org.springframework.web.multipart.MultipartFile;
  2.  
  3. public class MultipartFileParam {
  4. private String taskId;
  5. private int chunkNumber;
  6. private long chunkSize;
  7. private int totalChunks;
  8. private String identifier;
  9. private MultipartFile file;
  10.  
  11. public String getTaskId() {
  12. return taskId;
  13. }
  14.  
  15. public void setTaskId(String taskId) {
  16. this.taskId = taskId;
  17. }
  18.  
  19. public int getChunkNumber() {
  20. return chunkNumber;
  21. }
  22.  
  23. public void setChunkNumber(int chunkNumber) {
  24. this.chunkNumber = chunkNumber;
  25. }
  26.  
  27. public long getChunkSize() {
  28. return chunkSize;
  29. }
  30.  
  31. public void setChunkSize(long chunkSize) {
  32. this.chunkSize = chunkSize;
  33. }
  34.  
  35. public int getTotalChunks() {
  36. return totalChunks;
  37. }
  38.  
  39. public void setTotalChunks(int totalChunks) {
  40. this.totalChunks = totalChunks;
  41. }
  42.  
  43. public String getIdentifier() {
  44. return identifier;
  45. }
  46.  
  47. public void setIdentifier(String identifier) {
  48. this.identifier = identifier;
  49. }
  50.  
  51. public MultipartFile getFile() {
  52. return file;
  53. }
  54.  
  55. public void setFile(MultipartFile file) {
  56. this.file = file;
  57. }
  58. }

ChunkService类

  1. import org.apache.commons.codec.digest.DigestUtils;
  2. import org.apache.commons.io.FileUtils;
  3. import org.apache.commons.lang.StringUtils;
  4.  
  5. import java.io.File;
  6. import java.io.FileInputStream;
  7. import java.io.IOException;
  8. import java.io.RandomAccessFile;
  9. import java.nio.ByteBuffer;
  10. import java.nio.channels.FileChannel;
  11. import java.util.UUID;
  12.  
  13. public class ChunkService {
  14. public String chunkUploadByMappedByteBuffer(MultipartFileParam param, String filePath) throws IOException, NotSameFileExpection {
  15.  
  16. if (param.getTaskId() == null || "".equals(param.getTaskId())) {
  17. param.setTaskId(UUID.randomUUID().toString());
  18. }
  19.  
  20. String fileName = param.getFile().getOriginalFilename();
  21. String tempFileName = param.getTaskId() + fileName.substring(fileName.lastIndexOf(".")) + "_tmp";
  22. File fileDir = new File(filePath);
  23. if (!fileDir.exists()) {
  24. fileDir.mkdirs();
  25. }
  26. File tempFile = new File(filePath, tempFileName);
  27. //第一步 打开将要写入的文件
  28. RandomAccessFile raf = new RandomAccessFile(tempFile, "rw");
  29. //第二步 打开通道
  30. FileChannel fileChannel = raf.getChannel();
  31. //第三步 计算偏移量
  32. long position = (param.getChunkNumber() - 1) * param.getChunkSize();
  33. //第四步 获取分片数据
  34. byte[] fileData = param.getFile().getBytes();
  35. //第五步 写入数据
  36. fileChannel.position(position);
  37. fileChannel.write(ByteBuffer.wrap(fileData));
  38. fileChannel.force(true);
  39. fileChannel.close();
  40. raf.close();
  41. //判断是否完成文件的传输并进行校验与重命名
  42. boolean isComplete = checkUploadStatus(param, fileName, filePath);
  43. if (isComplete) {
  44. FileInputStream fileInputStream = new FileInputStream(tempFile.getPath());
  45. String md5 = DigestUtils.md5Hex(fileInputStream);
  46. fileInputStream.close();
  47. if (StringUtils.isNotBlank(md5) && !md5.equals(param.getIdentifier())) {
  48. throw new NotSameFileExpection();
  49. }
  50. renameFile(tempFile, fileName);
  51. return fileName;
  52. }
  53. return null;
  54. }
  55.  
  56. public void renameFile(File toBeRenamed, String toFileNewName) {
  57. if (!toBeRenamed.exists() || toBeRenamed.isDirectory()) {
  58. System.err.println("文件不存在");
  59. return;
  60. }
  61. String p = toBeRenamed.getParent();
  62. File newFile = new File(p + File.separatorChar + toFileNewName);
  63. toBeRenamed.renameTo(newFile);
  64. }
  65.  
  66. public boolean checkUploadStatus(MultipartFileParam param, String fileName, String filePath) throws IOException {
  67. File confFile = new File(filePath, fileName + ".conf");
  68. RandomAccessFile confAccessFile = new RandomAccessFile(confFile, "rw");
  69. //设置文件长度
  70. confAccessFile.setLength(param.getTotalChunks());
  71. //设置起始偏移量
  72. confAccessFile.seek(param.getChunkNumber() - 1);
  73. //将指定的一个字节写入文件中 127,
  74. confAccessFile.write(Byte.MAX_VALUE);
  75. byte[] completeStatusList = FileUtils.readFileToByteArray(confFile);
  76. confAccessFile.close();//不关闭会造成无法占用
  77. //创建conf文件文件长度为总分片数,每上传一个分块即向conf文件中写入一个127,那么没上传的位置就是默认的0,已上传的就是127
  78. for (int i = 0; i < completeStatusList.length; i++) {
  79. if (completeStatusList[i] != Byte.MAX_VALUE) {
  80. return false;
  81. }
  82. }
  83. confFile.delete();
  84. return true;
  85. }
  86. }

6.NotSameFileExpection类

  1. public class NotSameFileExpection extends Exception {
  2. public NotSameFileExpection() {
  3. super("File MD5 Different");
  4. }
  5. }

遇到问题

根据自己的实际情况进行取舍,灵活处理。

以上这篇vue-simple-uploader上传成功之后的response获取代码就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

原文链接:https://blog.csdn.net/BennyShi1998/article/details/79326551

相关文章

热门资讯

yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
2021年耽改剧名单 2021要播出的59部耽改剧列表
2021年耽改剧名单 2021要播出的59部耽改剧列表 2021-03-05
返回顶部