IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> springboot + vue + vue-simple-uploader 实现大文件分片上传 -> 正文阅读

[JavaScript知识库]springboot + vue + vue-simple-uploader 实现大文件分片上传

原文章?https://www.cnblogs.com/hz-handofgod/p/11985170.html? 适当修改

参考官方组件文档?https://github.com/simple-uploader/vue-uploader

目录

前台VUE

后台

效果图


前台VUE

?添加npm包

npm install vue-simple-uploader --save

?main.js

import upLoader from 'vue-simple-uploader'
Vue.use(upLoader)

vue页面

<template>
  <div>
    <div>
      <uploader
        :options="options"
        :file-status-text="statusText"
        class="uploader-example"
        ref="uploader"
        @file-success="fileSuccess"
        @file-error="fileError"
        style="width: 100%;"
      >
        <uploader-unsupport></uploader-unsupport>
        <uploader-drop>
          <p>上传界面</p>
          <uploader-btn single>选择文件</uploader-btn>
        </uploader-drop>
        <uploader-list></uploader-list>
      </uploader>
    </div>
  </div>
</template>

<script>
export default {
  name: 'UploadTest',
  data() {
    return {
      recording: {},
      options: {
        // https://github.com/simple-uploader/Uploader/tree/develop/samples/Node.js
        target: '/apis/upload/uploadChunk', //后台上传文件地址
        testChunks: false, //不校验
        chunkSize: 2048000 //每片大小
      },
      statusText: {
        success: '上传成功',
        error: '上传失败',
        uploading: '上传中',
        paused: '暂停中',
        waiting: '等待中'
      }
    }
  },
  methods: {
    //上传成功的回调事件
    fileSuccess(rootFile, file, message, chunk) {
      var name = message.split('\\')
      var nameLast = name[name.length - 1]
      // 文件链接
      this.recording.recordingUrl = 'http://localhost:8090/static/' + nameLast
      // 打印访问服务器的文件地址
      alert(this.recording.recordingUrl)
    },
    fileError() {

    }
  },
  mounted() {
    // 获取uploader对象
    this.$nextTick(() => {
      window.uploader = this.$refs.uploader.uploader
    })
  }
}
</script>

<style scoped>
.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>

关于上传选择文件的单选多选,uploader-btn标签的single属性控制

页面展示效果

后台

pom添加两个依赖

     <!--文件上传-->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.1</version>
        </dependency>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>

util文件?Uploader

package com.cei.xyd_association.util;


import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.Iterator;

/**
 * 断点续传
 *
 * @author 
 */
public class Uploader {
    /**
     * 临时文件夹
     */
    private String temporaryFolder;
    /**
     * 最大文件大小 2GB
     */
    private Integer maxFileSize = 2048000000;
    // private String fileParameterName;

    public Uploader(String temporaryFolder, String fileParameterName) {
        this.temporaryFolder = temporaryFolder;
        File file = new File(temporaryFolder);
        if (!file.exists()) {
            file.mkdirs();
        }
        // if (fileParameterName == null) {
        // this.fileParameterName = "file";
        // } else {
        // this.fileParameterName = fileParameterName;
        // }
    }

    public String cleanIdentifier(String identifier) {
        return identifier.replaceAll("[^0-9A-Za-z_-]", "");
    }

    public String getChunkFilename(int chunkNumber, String identifier) {
        identifier = cleanIdentifier(identifier);
        return new File(temporaryFolder, "jwj-" + identifier + '-' + chunkNumber).getAbsolutePath();
    }

    public String validateRequest(int chunkNumber, int chunkSize, int totalSize, String identifier, String filename,
                                  Integer fileSize) {
        identifier = cleanIdentifier(identifier);

        if (chunkNumber == 0 || chunkSize == 0 || totalSize == 0 || identifier.length() == 0
                || filename.length() == 0) {
            return "non_uploader_request";
        }
        int numberOfChunks = (int) Math.max(Math.floor(totalSize / (chunkSize * 1.0)), 1);
        if (chunkNumber > numberOfChunks) {
            return "invalid_uploader_request1";
        }

        if (this.maxFileSize != null && totalSize > this.maxFileSize) {
            return "invalid_uploader_request2";
        }

        if (fileSize != null) {
            if (chunkNumber < numberOfChunks && fileSize != chunkSize) {
                return "invalid_uploader_request3";
            }
            if (numberOfChunks > 1 && chunkNumber == numberOfChunks
                    && fileSize != ((totalSize % chunkSize) + chunkSize)) {
                return "invalid_uploader_request4";
            }
            if (numberOfChunks == 1 && fileSize != totalSize) {
                return "invalid_uploader_request5";
            }
        }

        return "valid";
    }

    public int getParamInt(HttpServletRequest req, String key, int def) {
        String value = req.getParameter(key);
        try {
            return Integer.parseInt(value);
        } catch (Exception e) {
        }
        return def;
    }

    public String getParamString(HttpServletRequest req, String key, String def) {
        String value = req.getParameter(key);
        try {
            return value == null ? def : value;
        } catch (Exception e) {
        }
        return def;
    }

    public void get(HttpServletRequest req, UploadListener listener) {
        int chunkNumber = this.getParamInt(req, "chunkNumber", 0);
        int chunkSize = this.getParamInt(req, "chunkSize", 0);
        int totalSize = this.getParamInt(req, "totalSize", 0);
        String identifier = this.getParamString(req, "identifier", "");
        String filename = this.getParamString(req, "filename", "");
        if (validateRequest(chunkNumber, chunkSize, totalSize, identifier, filename, null).equals("valid")) {
            String chunkFilename = getChunkFilename(chunkNumber, identifier);
            if (new File(chunkFilename).exists()) {
                listener.callback("found", chunkFilename, filename, identifier, null);
            } else {
                listener.callback("not_found", null, null, null, null);
            }

        } else {
            listener.callback("not_found", null, null, null, null);
        }
    }

    public void post(HttpServletRequest req, UploadListener listener) throws IllegalStateException, IOException {

        int chunkNumber = this.getParamInt(req, "chunkNumber", 0);
        int chunkSize = this.getParamInt(req, "chunkSize", 0);
        int totalSize = this.getParamInt(req, "totalSize", 0);
        String identifier = this.getParamString(req, "identifier", "");
        String filename = this.getParamString(req, "filename", "");

        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(req.getSession().getServletContext());

        if (multipartResolver.isMultipart(req)) {
            // 将request变成多部分request
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) req;
            // 获取multiRequest 中所有的文件名
            Iterator<String> iter = multiRequest.getFileNames();
            while (iter.hasNext()) {
                String name = iter.next().toString();
                // if (!this.fileParameterName.equals(name)) {
                // continue;
                // }
                MultipartFile file = multiRequest.getFile(name);

                if (file != null && file.getSize() > 0) {
                    String original_filename = file.getOriginalFilename();
                    // String original_filename =
                    // files[this.fileParameterName]['originalFilename'];
                    String validation = validateRequest(chunkNumber, chunkSize, totalSize, identifier, filename,
                            (int) file.getSize());

                    if ("valid".equals(validation)) {
                        String chunkFilename = getChunkFilename(chunkNumber, identifier);

                        File f = new File(chunkFilename);
                        if (!f.exists()) {
                            file.transferTo(f);
                        }

                        int currentTestChunk = 1;
                        int numberOfChunks = (int) Math.max(Math.floor(totalSize / (chunkSize * 1.0)), 1);

                        currentTestChunk = this.testChunkExists(currentTestChunk, chunkNumber, numberOfChunks,
                                chunkFilename, original_filename, identifier, listener, "file");

                    } else {
                        listener.callback(validation, filename, original_filename, identifier, "file");
                    }
                } else {
                    listener.callback("invalid_uploader_request", null, null, null, null);
                }
            }
        }
    }

    private void pipeChunk(int number, String identifier, UploadOptions options, OutputStream writableStream)
            throws IOException {
        String chunkFilename = getChunkFilename(number, identifier);
        if (new File(chunkFilename).exists()) {
            FileInputStream inputStream = new FileInputStream(new File(chunkFilename));
            int maxlen = 1024;
            int len = 0;
            try {
                byte[] buff = new byte[maxlen];
                while ((len = inputStream.read(buff, 0, maxlen)) > 0) {
                    writableStream.write(buff, 0, len);
                }
            } finally {
                inputStream.close();
            }
            pipeChunk(number + 1, identifier, options, writableStream);
        } else {
            if (options.end)
                writableStream.close();
            if (options.listener != null)
                options.listener.onDone();
        }
    }

    public void write(String identifier, OutputStream writableStream, UploadOptions options) throws IOException {
        if (options == null) {
            options = new UploadOptions();
        }
        if (options.end == null) {
            options.end = true;
        }
        pipeChunk(1, identifier, options, writableStream);
    }

    /**
     * @param currentTestChunk
     * @param chunkNumber       当前上传块
     * @param numberOfChunks    总块数
     * @param filename          文件名称
     * @param original_filename 源文件名称
     * @param identifier        文件
     * @param listener          监听
     * @param fileType
     * @return
     */
    private int testChunkExists(int currentTestChunk, int chunkNumber, int numberOfChunks, String filename,
                                String original_filename, String identifier, UploadListener listener, String fileType) {
        String cfile = getChunkFilename(currentTestChunk, identifier);
        if (new File(cfile).exists()) {
            currentTestChunk++;
            if (currentTestChunk >= chunkNumber) {
                if (chunkNumber == numberOfChunks) {
                    try {
                        System.out.println("done");
                        // 文件合并
                        UploadOptions options = new UploadOptions();
                        File f = new File(this.temporaryFolder, original_filename.substring(0, original_filename.lastIndexOf("."))
                                + "-" + UUIDUtil.getUUID_36() + "." + FilenameUtils.getExtension(original_filename));
                        options.listener = new UploadDoneListener() {
                            @Override
                            public void onError(Exception err) {
                                listener.callback("invalid_uploader_request", f.getAbsolutePath(), original_filename,
                                        identifier, fileType);
                                clean(identifier, null);
                            }

                            @Override
                            public void onDone() {
                                listener.callback("done", f.getAbsolutePath(), original_filename, identifier, fileType);
                                clean(identifier, null);
                            }
                        };
                        this.write(identifier, new FileOutputStream(f), options);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                        listener.callback("invalid_uploader_request", filename, original_filename, identifier,
                                fileType);
                    } catch (IOException e) {
                        e.printStackTrace();
                        listener.callback("invalid_uploader_request", filename, original_filename, identifier,
                                fileType);
                    }
                } else {
                    listener.callback("partly_done", filename, original_filename, identifier, fileType);
                }
            } else {
                return testChunkExists(currentTestChunk, chunkNumber, numberOfChunks, filename, original_filename,
                        identifier, listener, fileType);
            }
        } else {
            listener.callback("partly_done", filename, original_filename, identifier, fileType);
        }
        return currentTestChunk;
    }

    public void clean(String identifier, UploadOptions options) {
        if (options == null) {
            options = new UploadOptions();
        }
        pipeChunkRm(1, identifier, options);
    }

    private void pipeChunkRm(int number, String identifier, UploadOptions options) {

        String chunkFilename = getChunkFilename(number, identifier);
        File file = new File(chunkFilename);
        if (file.exists()) {
            try {
                file.delete();
            } catch (Exception e) {
                if (options.listener != null) {
                    options.listener.onError(e);
                }
            }
            pipeChunkRm(number + 1, identifier, options);

        } else {
            if (options.listener != null)
                options.listener.onDone();
        }
    }

    public static interface UploadListener {
        public void callback(String status, String filename, String original_filename, String identifier,
                             String fileType);
    }

    public static interface UploadDoneListener {
        public void onDone();

        public void onError(Exception err);
    }

    public static class UploadOptions {
        public Boolean end;
        public UploadDoneListener listener;
    }
}

这里面需要改两个地方

maxFileSize 设置上传的文件大小最大限制

UUIDUtil.getUUID_36()? 这个是我项目自己的UUID随机生成的工具类方法,自己弄一套生成就行

util文件?UploadUtils

package com.cei.xyd_association.util;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;

import javax.servlet.http.HttpServletRequest;

import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

public class UploadUtils {

    public String upload(HttpServletRequest request) {
        String path = "F:/tmp/";
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        if (multipartResolver.isMultipart(request)) {
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            Iterator<String> iter = multiRequest.getFileNames();
            while (iter.hasNext()) {
                // 一次遍历所有文件
                MultipartFile file = multiRequest.getFile(iter.next().toString());
                if (file != null) {
                    String p = path + "/" + file.getOriginalFilename();
                    // 上传
                    try {
                        file.transferTo(new File(p));
                        return p;
                    } catch (IllegalStateException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return null;
    }
}

自己改下自己的path就行?

controller

package com.cei.xyd_association.web;

import com.cei.xyd_association.service.impl.UploadService;
import com.cei.xyd_association.util.UploadUtils;
import com.cei.xyd_association.util.Uploader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

@RestController
@RequestMapping("/upload")
public class uploadController {

    @Resource
    private UploadService uploadService;

    /**
     * 分片上传
     *
     * @param request  前台发送过来的文件内容
     * @param response 响应给前台文件路径
     * @throws Exception
     */
    @RequestMapping(value = "/uploadChunk", method = RequestMethod.POST)
    public void upload2(HttpServletRequest request, HttpServletResponse response) throws Exception {
        final String[] filepath = {""};
        final String[] or_filename = {""};
        try {
            uploadService.post(request, new Uploader.UploadListener() {
                @Override
                public void callback(String status, String filename, String original_filename, String identifier, String fileType) {
                    if (status != null) {
                        System.out.println(filename);
                    }
                    filepath[0] = filename;//文件上传的路径带走
                    or_filename[0] = original_filename;//源文件名称带走
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
        //这句话的意思,是让浏览器用utf8来解析返回的数据
        response.setHeader("Content-type", "text/html;charset=UTF-8");
        //这句话的意思,是告诉servlet用UTF-8转码,而不是用默认的ISO8859
        response.setCharacterEncoding("UTF-8");
        response.getWriter().append(filepath[0]);
    }

    @ResponseBody
    @RequestMapping(path = "/upload2", method = RequestMethod.POST)
    public void upload(HttpServletRequest request, HttpServletResponse response) {
        new UploadUtils().upload(request);
        this.success(response, "上传成功!");
    }


    public void success(HttpServletResponse response, Object obj) {
        PrintWriter writer = null;
        try {
            writer = response.getWriter();
            writer.write(obj.toString());
        } catch (Exception e) {
        } finally {
            if (writer != null) {
                //writer.close();
            }
        }
    }
}

这里我把?response.getWriter().append(filepath[0]); 改了,因为我们需求返回给前台能访问服务器的文件路径,所以返回文件名方便拼地址

?Service文件 UploadService

package com.cei.xyd_association.service.impl;


import com.cei.xyd_association.util.Uploader;
import org.springframework.stereotype.Service;

@Service
public class UploadService extends Uploader {
    public UploadService(){
        super("F:/tmp/","file");
    }
}

还是改自己存文件的地方

访问映射

application添加

#上传文件的路径和映射地址
#本地存放路径
localFileUrl: F:\tmp
#映射的网络url
mappingFileUrl: /static/

?application的server设置

?

?访问本地资源的启动配置

package com.cei.xyd_association.config;

import com.cei.xyd_association.Interceptor.TESTInterceptor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class MyWebAppConfiguration extends WebMvcConfigurerAdapter {

    @Value("${localFileUrl}")
    private String localFileUrl;//本地存放的文件路径 例如:E:\down
    @Value("${mappingFileUrl}")
    private String mappingFileUrl;//映射的虚拟网络地址  供页面连接访问的url

    @Bean
    public TESTInterceptor getSessionInterceptor() {
        return new TESTInterceptor();
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler(mappingFileUrl+"**").addResourceLocations("file:"+localFileUrl+"/");
    }

    /**
     * 拦截器
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(getSessionInterceptor())
                .addPathPatterns("/**");
    }

}

效果图

前台切分片

?后台上传分片

?分片文件

?最后传完合并

前台alert出文件在服务器的地址

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-24 00:26:06  更:2022-03-24 00:26:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:05:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码