java webupload实例,web前端分片上传demo(基于webuploader)

首先简短解释下断点续传的原理:

???? 客户端选取文件,通过webuploader进行MD5然后进行分片,每一个分片均需要进行上传前检查(检查当前分片时候已经上传),如果没有上传就开始进行上传,最后在上传完成之后会调用一个合并的操作,在后台将所有分片依次合并,按照指定文件名生成文件。

1.准备工作:

???? 1)前端使用jquery(jquery-1.10.2.js),webuploader插件(webuploader-0.1.5)

???? 2)后台准备 springMvc(使用注解,配置requestMapping)

??? 3)开发环境 jsp,MyEclipse 1.0

2.开发步骤:

??? 1)集成springMvc,此处步骤相对简单(可按照: http://www.jianshu.com/p/0ccaa4af05fc)。

??? 2)导入jquery , webuploader,编写前台页面,代码如下:

??

class="js">

断点续传

// 监听分块上传的时间点,断点续传

var fileMd5; //保存文件MD5名称

var uploader; //全局对象uploader

WebUploader.Uploader.register(

{"before-send-file" : "beforeSendFile", //文件上传之前执行

"before-send" : "beforeSend",//文件块上传之前执行

"after-send-file" : "afterSendFile", //上传完成之后执行

},

{

//时间点1:所有进行上传之前调用此函数

beforeSendFile : function(file) {

var deferred = WebUploader.Deferred();

// 计算文件的唯一标识,用于断点续传和妙传

(new WebUploader.Uploader()).md5File(file, 0,

10 * 1024 * 1024).progress(

function(percentage) {

$("#" + file.id).find("span.state").text("正在获取文件信息...");

}).then(

function(val) {

fileMd5 = val;

$("#" + file.id).find("span.state").text("成功获取文件信息");

// 放行

deferred.resolve();

});

return deferred.promise();

},

//每一个分块发送之前执行该操作,检查当前块是否已经上传

beforeSend : function(block) {

var deferred = WebUploader.Deferred();

$.ajax({

type : "POST",

url : "${ctx}/system/upload/testUploadMergeUploadFile.htm?action=checkChunk",

data : {

//文件唯一标记

fileMd5 : fileMd5,

//当前分块下标

chunk : block.chunk,

//当前分块大小

chunkSize : block.end - block.start

},

dataType : "json",

success : function(response) {

if (response.ifExist) {

//分块存在,跳过

deferred.reject();

} else {

//分块不存在或不完整,重新发送该分块内容

deferred.resolve();

}

}

});

this.owner.options.formData.fileMd5 = fileMd5;

return deferred.promise();

},

afterSendFile : function(file) {

// 通知合并分块

$.ajax({

type : "POST",

url : "/RenWei/system/upload/testUploadMergeUploadFile.htm?action=mergeChunks",

data : {

'fileMd5' : fileMd5

},

success : function(response) {

var $li = $('#' + file.id);

$li.find('p.state').text('上传完成');

$("#ctlBtn").addClass('disabled');

}

});

}

});

$(function() {

// 上传基本配置

uploader = WebUploader.create({

swf : "${ctx}/root/comm/webuploader-0.1.5/Uploader.swf",

server : '${ctx}/system/upload/testUploadSaveFile.htm',

pick : "#filePicker",

auto : false,

// 分块上传设置

// 是否分块

chunked : true,

// 每块文件大小(默认5M)

chunkSize : 10 * 1024 * 1024,

// 开启几个并非线程(默认3个)

threads : 1,

// 在上传当前文件时,准备好下一个文件

formData : { //这里可以自定义属性,在后台全部都可以接收

fileMd5 : fileMd5

},

prepareNextFile : true

});

// 选中文件之后触发

uploader.on("fileQueued", function(file) {

// 把文件信息追加到fileList的div中

$("#fileList").append(

'

'

+ '

' + file.name + '

'

+ '

等待上传...

' + '
');

//md5计算

uploader.md5File(file).progress(function(percentage) {

console.log('Percentage:', percentage);

})

// 完成

.then(function(md5File) { // 完成

fileMd5 = md5File;

$('#' + file.id).find('p.state').text('MD5计算完毕,可以点击上传了');

$("#ctlBtn").removeClass('disabled');

});

});

// 监控上传进度

// percentage:代表上传文件的百分比

// 文件上传过程中创建进度条实时显示。

uploader.on('uploadProgress', function(file, percentage) {

var $li = $('#' + file.id);

$li.find('p.state').text('上传中 '+Math.round(percentage * 100) + '%');

});

$("#ctlBtn").on('click', function() {

if ($(this).hasClass('disabled')) {

alert("请选择文件或等待文件生成MD5完成。");

return false;

}

uploader.options.formData['fileMd5'] = fileMd5;

uploader.upload();

});

});

选择文件

开始上传

0%

?-----------------------------------------------------------------华丽的分割线--------------------------------------------------

?

至此前台代码已经完成:

? 3)开始编写后台代码:

?

@Controller

@RequestMapping("/system/upload")

public class TestUpload {

String serverPath = "d:\\"; //临时目录

/*

* 保存文件,数据块

*/

@SuppressWarnings("unchecked")

@RequestMapping("testUploadSaveFile.htm")

public void saveFile(HttpServletRequest request,

HttpServletResponse response) {

DiskFileItemFactory factory = new DiskFileItemFactory();

ServletFileUpload upload = new ServletFileUpload(factory);

try {

List items = upload.parseRequest(request);

UploadUtil.saveChunkData(items);

} catch (FileUploadException e) {

e.printStackTrace();

}

}

//合并上传文件

@RequestMapping("testUploadMergeUploadFile.htm")

public void mergeUploadFile(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

System.out.println("进入合并后台...");

String action = request.getParameter("action");

String saveFilePath = ConfigUtil.getInstance().getProValue("saveChunkFilePath");

String fileMd5 = request.getParameter("fileMd5");

if("mergeChunks".equals(action)){

UploadUtil.mergeUploadFile(saveFilePath, fileMd5);

}

else if("checkChunk".equals(action)){

// 当前分块下标

String chunk = request.getParameter("chunk");

// 当前分块大小

String chunkSize = request.getParameter("chunkSize");

String yesOrNoFlag = UploadUtil.checkChunk(saveFilePath+"/"+fileMd5, chunk, chunkSize);

if(yesOrNoFlag.equals("1")){

response.getWriter().write("{\"ifExist\":"+yesOrNoFlag+"}");

}

else{

response.getWriter().write("{\"ifExist\":"+yesOrNoFlag+"}");

}

}

}

}

??? 具体的上传方法我已经抽象出来了(上述代码中的UploadUtil.mergeUploadFile(saveFilePath, fileMd5),UploadUtil.saveChunkData(items))两个方法。

),

?

??? 代码如下:?

?????? 哟,抽象出来的还是放在附件中了(UploadUtil.java),这样大家想用的话直接复制就好。^_^^_^^_^^_^^_^

?

?

好了,到目前未知我们所有的工作都已经完成了,就可以直接将代码发布在中间件上,直接查看方才编写的

jsp了。

?

正常情况下都是可以上传成功的,并且有进度条显示上传的进度。

?

如果不成功的话,可参照一下步骤检查:

? 1.WebUploader.Uploader.register (1.2.3) 三个方法必须放置在最前边,且不能放置在$(function(){...})

中,都则1.2.3三个方法不生效,原因是作用域链问题。

? 2.同一个分片多次上传仍然覆盖问题,每一个分片检查完成之后的放行,阻断方法问题,deferred.reject();

deferred.resolve();? 主要是deferred 延迟对象在检查完成之后不管结果全部放行。解决方案: 严格按照我代码中的写法,就没有问题。

?

最后如果还有什么问题,比如发现代码中逻辑错误,不够严谨,都可以直接联系我,

微信: ma0603kang

?