官方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个片