springboot+webuploader实现大文件分片上传 带动态效果演示图 代码copy即用无需再次下载js、css等

官方API:http://fex.baidu.com/webuploader/doc/index.html

1、前端代码 

文件接收服务端 需要修改为你自己后台的server路径

<!DOCTYPE html
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <link href="https://cdn.staticfile.org/webuploader/0.1.5/webuploader.css" rel="stylesheet" type="text/css" />
  <script type="text/javascript" src="http://cdn.staticfile.org/jquery/1.10.2/jquery.js"></script>
  <script type="text/javascript" src="http://cdn.staticfile.org/webuploader/0.1.5/webuploader.min.js"></script>
</head>

<body>
  <div class="col-xs-6">
    <div class="btns">
      <div id="picker">选择文件</div>
      <button id="uploadctlBtn" class="btn btn-primary">开始上传</button>
      <button id="stopctlBtn" class="btn btn-primary">暂停上传</button>
    </div>
  </div>

  <!--用来存放文件信息-->
  <div id="thelist" class="uploader-list col-xs-7"></div>

  <div class="col-xs-5">
    <div class="row">
      <div id="error-list" class="col-xs-12"></div>
      <div id="success-list" class="col-xs-12"></div>
    </div>
  </div>
</body>

<script type="text/javascript">
  // 文件上传
  jQuery(function () {
    var $ = jQuery,
      $list = $('#thelist'),
      $btn = $('#uploadctlBtn'),
      $stopctlBtn = $('#stopctlBtn'),
      /* state = 'pending',*/
      uploader;


    uploader = WebUploader.create({
      // 不压缩image
      resize: false,
      // swf文件路径
      swf: 'http://cdn.staticfile.org/webuploader/0.1.5/Uploader.swf',
      // 文件接收服务端 (改成你自己后端接口的地址)
      server: 'http://127.0.0.1:8006/rescueTycoon/upload2',
      // 选择文件的按钮。可选。
      // 内部根据当前运行是创建,可能是input元素,也可能是flash.
      pick: '#picker',
      dnd: '#thelist',
      chunked: true,  // 分片处理
      chunkSize: 100 * 1024 * 1024, // 每片100M,
      chunkRetry: false  // 如果失败,则不重试
    });


    // 当有文件添加进来的时候
    uploader.on('fileQueued', function (file) {
      $list.append('<div id="' + file.id + '" class="item row">' +
        '<div class="col-xs-3" >' + file.name + '</div>' +
        '<div class="col-xs-4" ><div class="progress progress-striped active"><div class="progress-bar" role="progressbar" style="width: 0%"><span></span></div></div></div>' +
        '<div class="col-xs-2" ><p class="state">等待上传...</p></div>' +
        '<div class="col-xs-2" ><span class="retry">重试</span><span class="stop"></span><span class="cancel">取消</span></div>' +
        '</div>');
    });


    function getFilesInfo(id, file, uploadStates) {
      var stateMsg;
      if (uploadStates) {
        stateMsg = '上传成功';
      } else {
        stateMsg = '上传失败';
      }
      $('#' + id).append('<div id="' + file.id + '" class="item row">' +
        '<div class="col-xs-12 " >' + file.name + '<span></span></div>' +
        '</div>');
      $('#' + id + ' #' + file.id).find('span').text(stateMsg);
    }




    // 文件上传过程中创建进度条实时显示。
    uploader.on('uploadProgress', function (file, percentage) {
      $percent = $('#' + file.id).find('.progress .progress-bar');
      $('#' + file.id).find('p.state').text('上传中');
      $percent.css('width', percentage * 100 + '%');
      $percent.find('span').text(percentage.toFixed(2) * 100 + '%');
    });




    //上传成功
    uploader.on('uploadSuccess', function (file) {
      $('#' + file.id).find('p.state').text('上传成功');
      $('#' + file.id).find('.progress-bar').css('background-image', "none");
      $('#' + file.id).find('.cancel').remove();
      $('#' + file.id).find('.stop').remove();
      getFilesInfo('success-list', file, true);
    });




    //上传失败
    uploader.on('uploadError', function (file) {
      $('#' + file.id).find('.retry').css('display', "block");
      $percent = $('#' + file.id).find('.progress .progress-bar');
      $('#' + file.id).find('p.state').text('上传出错');
      $('#' + file.id).find('.progress-bar').css('width', 0 + '%');
      $percent.find('span').text('0%');
      $('#' + file.id).find('.cancel').remove();
      $('#' + file.id).find('.stop').remove();
      getFilesInfo('error-list', file, false);
      retry(file);
    });


    /* uploader.on( 'all', function( type ) {
         if ( type === 'startUpload' ) {
             state = 'uploading';
         } else if ( type === 'stopUpload' ) {
             state = 'paused';
         } else if ( type === 'uploadFinished' ) {
             state = 'done';
         }
     });*/




    var flag = true;
    uploader.onFileQueued = function (file) {
      $('#' + file.id).find('.cancel').on('click', function () {
        uploader.removeFile(file, true);
      });
      $('#' + file.id).find('.stop').on('click', function () {
        if (flag) {
          uploader.stop(file);
          $('#' + file.id).find('.stop').text('继续上传');
          flag = false;
        } else {
          uploader.upload(file);
          $('#' + file.id).find('.stop').text('暂停上传');
          flag = true;
        }
      });
    }


    $btn.on('click', function () {
      uploader.upload();
      $('#thelist').find('.stop').text('暂停上传');
      flag = true;
    });


    $stopctlBtn.on('click', function () {
      uploader.stop(true);
      $('#thelist').find('.stop').text('继续上传');
      flag = false;
    });


    function retry(file) {
      $('#' + file.id).find('.retry').on('click', function () {
        uploader.retry(file);
      })
    }


    //负责view的销毁
    uploader.onFileDequeued = function (file) {
      $('#' + file.id).off().find('.cancel').off().end().remove();
    };


    uploader.uploadComplete = function (file) {
      uploader.upload();
    }


  });

</script>

</html>

2、后端代码

yml配置上传限制文件大小

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/tree?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    username: root
    password: root
  # 文件上传限制
  servlet:
    multipart:
      enabled: true #是否启用http上传处理
      max-request-size: 800MB #最大请求文件的大小
      max-file-size: 100MB #设置单个文件最大长度 可根据你前端设置的分片大小来设置
      file-size-threshold: 500MB #当文件达到多少时进行磁盘写入

package com.xyz.rescuetycoon.shopping.controller;

import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Controller;
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.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Date;

@Controller
public class UploadController {
 

    @RequestMapping(value = "/upload2", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public double upload(MultipartFile file, String chunks, String chunk, String name, String size) {
        try {
            if (null != file) {
                long mStartTime = System.currentTimeMillis();
                //判断上传的文件是否被分片(小于100M的不会分片上传 前端可设置分片大小)
                if (null == chunks && null == chunk) {
                    //判断当前文件夹路径是否存在
                    newMkdirs(getResultFilePath());
                    //文件上传路径
                    File destTempFile = new File(getResultFilePath(), name);
                    //文件上传
                    file.transferTo(destTempFile);
                    //destTempFile.createNewFile();
                    long size1 = destTempFile.length();
                    long mEndTime = System.currentTimeMillis();
                    double speed = Long.parseLong(size) / ((mEndTime - mStartTime) * 1024);
                    double speed1 = 1014 / ((mEndTime - mStartTime));

                    System.out.println(new Date(mEndTime) + "" + new Date(mStartTime));
                    System.out.println(mEndTime - mStartTime);
                    System.out.println("size:" + size + "   start time:" + mStartTime + "     end time:" + mEndTime + "    speed:" + speed);
                    System.out.println("size:" + size1 + "   start time:" + mStartTime + "     end time:" + mEndTime + "    speed:" + speed1);
                    System.out.println();
                    return speed;
                }
                
                //开始进行分片操作
                String tempFileDir = getTempFilePath() + File.separator + name;
                File parentFileDir = new File(tempFileDir);
                if (!parentFileDir.exists()) {
                    parentFileDir.mkdirs();
                }
                File f = new File(tempFileDir + File.separator + name + "_" + chunk + ".part");
                file.transferTo(f);
                f.createNewFile();
                long size1 = f.length();
                long mEndTime = System.currentTimeMillis();
                double speed = Long.parseLong(size) / ((mEndTime - mStartTime) * 1024);
                double speed1 = 1014 / ((mEndTime - mStartTime));

                System.out.println(new Date(mEndTime) + "" + new Date(mStartTime));
                System.out.println(mEndTime - mStartTime);
                System.out.println("size:" + size + "   start time:" + mStartTime + "     end time:" + mEndTime + "    speed:" + speed);
                System.out.println("size:" + size1 + "   start time:" + mStartTime + "     end time:" + mEndTime + "    speed:" + speed1);
                System.out.println();
                // 是否全部上传完成
                // 所有分片都存在才说明整个文件上传完成
                boolean uploadDone = true;
                for (int i = 0; i < Integer.parseInt(chunks); i++) {
                    File partFile = new File(tempFileDir, name + "_" + i + ".part");
                    if (!partFile.exists()) {
                        uploadDone = false;
                        return speed;
                    }
                }
                // 所有分片文件都上传完成
                // 将所有分片文件合并到一个文件中
                if (uploadDone) {
                    synchronized (this) {
                        //判断当前文件夹路径是否存在
                        newMkdirs(getResultFilePath());
                        //文件上传的路径
                        File destTempFile = new File(getResultFilePath(), name);
                        //循环分片文件进行合并操作
                        for (int i = 0; i < Integer.parseInt(chunks); i++) {
                            File partFile = new File(tempFileDir, name + "_" + i + ".part");
                            FileOutputStream destTempfos = new FileOutputStream(destTempFile, true);
                            FileUtils.copyFile(partFile, destTempfos);
                            destTempfos.close();
                        }
                        //合并完文件之后删除分片
                        FileUtils.deleteDirectory(parentFileDir);
                    }
                }
                return speed;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 分片的位置
     *
     * @return
     */
    private String getTempFilePath() {
        return "D:/webUpload/back";
    }

    /**
     * 最终合并文件的位置
     *
     * @return
     */
    private String getResultFilePath() {
        return "D:/webUpload/result";
    }

    /**
     * 判断当前文件夹路径是否存在
     * 不存在则创建文件夹路径
     *
     * @param path
     */
    private void newMkdirs(String path) {
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
    }
}

效果演示

PS:因为这个文件大小是733MB

我在前端设置为了每次分片的大小为100MB 

所以分完片之后就会有0到7  8个片

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值