分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 前端开发

单文件WebUploader做大文件的分块和断点续传

发布时间:2023-09-06 01:35责任编辑:苏小强关键词:Web

前言:

WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件。在现代的浏览器里面能充分发挥HTML5的优势,同时又不摒弃主流IE浏览器,沿用原来的FLASH运行时,兼容IE6+,iOS 6+, android 4+。两套运行时,同样的调用方式,可供用户任意选用。

上面的一段话是来自http://fex.baidu.com/webuploader/ 的介绍,现在做的项目需要用到大文件的上传,之前没有做过,现有的jquery的uploadify只用于上传图片什么的小文件,查了网上的资料,这个插件好像对于大文件不是很友好,为了安全起见,使用百度的成熟框架,不论是多文件还是单个的大文件都是很好用的,没有很多的问题,关于webuploader的详细介绍看官网就行:

我的项目是javaweb,开发环境是MyEclipse,页面使用jsp

1、先将 webuploader-0.1.5.zip 这个文件下载下来:https://github.com/fex-team/webuploader/releases

根据个人的需求放置自己需要的东西就行,全部放到项目里也可以,下面是我自己需要的东西:

2、代码部分:分为jsp和servlet部分


1、jsp部分代码:

[html]view plaincopy
  1. <scripttype="text/javascript">
  2. varfileMd5;
  3. //监听分块上传过程中的三个时间点
  4. WebUploader.Uploader.register({
  5. "before-send-file":"beforeSendFile",
  6. "before-send":"beforeSend",
  7. "after-send-file":"afterSendFile",
  8. },{
  9. //时间点1:所有分块进行上传之前调用此函数
  10. beforeSendFile:function(file){
  11. vardeferred=WebUploader.Deferred();
  12. //1、计算文件的唯一标记,用于断点续传
  13. (newWebUploader.Uploader()).md5File(file,0,10*1024*1024)
  14. .progress(function(percentage){
  15. $(‘#item1‘).find("p.state").text("正在读取文件信息...");
  16. })
  17. .then(function(val){
  18. fileMd5=val;
  19. $(‘#item1‘).find("p.state").text("成功获取文件信息...");
  20. //获取文件信息后进入下一步
  21. deferred.resolve();
  22. });
  23. returndeferred.promise();
  24. },
  25. //时间点2:如果有分块上传,则每个分块上传之前调用此函数
  26. beforeSend:function(block){
  27. vardeferred=WebUploader.Deferred();
  28. $.ajax({
  29. type:"POST",
  30. url:"<%=basePath%>Video?action=checkChunk",
  31. data:{
  32. //文件唯一标记
  33. fileMd5:fileMd5,
  34. //当前分块下标
  35. chunk:block.chunk,
  36. //当前分块大小
  37. chunkSize:block.end-block.start
  38. },
  39. dataType:"json",
  40. success:function(response){
  41. if(response.ifExist){
  42. //分块存在,跳过
  43. deferred.reject();
  44. }else{
  45. //分块不存在或不完整,重新发送该分块内容
  46. deferred.resolve();
  47. }
  48. }
  49. });
  50. this.owner.options.formData.fileMd5=fileMd5;
  51. deferred.resolve();
  52. returndeferred.promise();
  53. },
  54. //时间点3:所有分块上传成功后调用此函数
  55. afterSendFile:function(){
  56. //如果分块上传成功,则通知后台合并分块
  57. $.ajax({
  58. type:"POST",
  59. url:"<%=basePath%>Video?action=mergeChunks",
  60. data:{
  61. fileMd5:fileMd5,
  62. },
  63. success:function(response){
  64. alert("上传成功");
  65. varpath="uploads/"+fileMd5+".mp4";
  66. $("#item1").attr("src",path);
  67. }
  68. });
  69. }
  70. });
  71. varuploader=WebUploader.create({
  72. //swf文件路径
  73. swf:‘<%=basePath%>scripts/webuploader-0.1.5/Uploader.swf‘,
  74. //文件接收服务端。
  75. server:‘<%=basePath%>UploadVideo‘,
  76. //选择文件的按钮。可选。
  77. //内部根据当前运行是创建,可能是input元素,也可能是flash.
  78. pick:{id:‘#add_video‘,<spanstyle="background-color:rgb(255,204,0);">//这个id是你要点击上传文件的id,自己设置就好</span>
  79. multiple:false},
  80. //不压缩image,默认如果是jpeg,文件上传前会压缩一把再上传!
  81. resize:true,
  82. auto:true,
  83. //开启分片上传
  84. chunked:true,
  85. chunkSize:10*1024*1024,
  86. accept:{
  87. //限制上传文件为MP4
  88. extensions:‘mp4‘,
  89. mimeTypes:‘video/mp4‘,
  90. }
  91. });
  92. //当有文件被添加进队列的时候
  93. uploader.on(‘fileQueued‘,function(file){
  94. $(‘#item1‘).empty();
  95. $(‘#item1‘).html(‘<div>‘+
  96. ‘<a>[取消上传]</a>‘+
  97. ‘<p>‘+file.name+‘</p>‘+
  98. ‘<p>等待上传...</p></div>‘
  99. );
  100. });
  101. //文件上传过程中创建进度条实时显示。
  102. uploader.on(‘uploadProgress‘,function(file,percentage){
  103. $(‘#item1‘).find(‘p.state‘).text(‘上传中‘+Math.round(percentage*100)+‘%‘);
  104. });
  105. uploader.on(‘uploadSuccess‘,function(file){
  106. $(‘#‘+file.id).find(‘p.state‘).text(‘已上传‘);
  107. });
  108. uploader.on(‘uploadError‘,function(file){
  109. $(‘#‘+file.id).find(‘p.state‘).text(‘上传出错‘);
  110. });
  111. uploader.on(‘uploadComplete‘,function(file){
  112. $(‘#‘+file.id).find(‘.progress‘).fadeOut();
  113. });
  114. functionstart(){
  115. uploader.upload();
  116. $(‘#btn‘).attr("onclick","stop()");
  117. $(‘#btn‘).text("取消上传");
  118. }
  119. functionstop(){
  120. uploader.stop(true);
  121. $(‘#btn‘).attr("onclick","start()");
  122. $(‘#btn‘).text("继续上传");
  123. }
  124. </script>

2、servlet部分代码:


servlet部分需要两个servlet,一个用于接收分块文件,一个用于合并分块成一个文件:

1、接收分块servlet代码:

[java]view plaincopy
  1. @SuppressWarnings("serial")
  2. publicclassUploadVideoextendsHttpServlet{
  3. @Override
  4. protectedvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)
  5. throwsServletException,IOException{
  6. //TODOAuto-generatedmethodstub
  7. super.doGet(req,resp);
  8. doPost(req,resp);
  9. }
  10. @SuppressWarnings("unchecked")
  11. publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)
  12. throwsServletException,IOException{
  13. DiskFileItemFactoryfactory=newDiskFileItemFactory();
  14. ServletFileUploadsfu=newServletFileUpload(factory);
  15. sfu.setHeaderEncoding("utf-8");
  16. StringsavePath=this.getServletConfig().getServletContext()
  17. .getRealPath("");
  18. Stringfolad="uploads";
  19. savePath=savePath+"\\"+folad+"\\";
  20. StringfileMd5=null;
  21. Stringchunk=null;
  22. try{
  23. List<FileItem>items=sfu.parseRequest(request);
  24. for(FileItemitem:items){
  25. if(item.isFormField()){
  26. StringfieldName=item.getFieldName();
  27. if(fieldName.equals("fileMd5")){
  28. fileMd5=item.getString("utf-8");
  29. }
  30. if(fieldName.equals("chunk")){
  31. chunk=item.getString("utf-8");
  32. }
  33. }else{
  34. Filefile=newFile(savePath+"/"+fileMd5);
  35. if(!file.exists()){
  36. file.mkdir();
  37. }
  38. FilechunkFile=newFile(savePath+"/"+fileMd5+"/"+chunk);
  39. FileUtils.copyInputStreamToFile(item.getInputStream(),chunkFile);
  40. }
  41. }
  42. }catch(FileUploadExceptione){
  43. //TODOAuto-generatedcatchblock
  44. e.printStackTrace();
  45. }
  46. }
  47. }

2、合并分块servlet代码:

[java]view plaincopy
  1. @SuppressWarnings("serial")
  2. publicclassVideoextendsHttpServlet{
  3. publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)
  4. throwsServletException,IOException{
  5. super.doGet(request,response);
  6. doPost(request,response);
  7. }
  8. publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)
  9. throwsServletException,IOException{
  10. StringsavePath=this.getServletConfig().getServletContext()
  11. .getRealPath("");
  12. Stringfolad="uploads";
  13. savePath=savePath+"\\"+folad+"\\";
  14. Stringaction=request.getParameter("action");
  15. if(action.equals("mergeChunks")){
  16. //合并文件
  17. //需要合并的文件的目录标记
  18. StringfileMd5=request.getParameter("fileMd5");
  19. //读取目录里的所有文件
  20. Filef=newFile(savePath+"/"+fileMd5);
  21. File[]fileArray=f.listFiles(newFileFilter(){
  22. //排除目录只要文件
  23. @Override
  24. publicbooleanaccept(Filepathname){
  25. //TODOAuto-generatedmethodstub
  26. if(pathname.isDirectory()){
  27. returnfalse;
  28. }
  29. returntrue;
  30. }
  31. });
  32. //转成集合,便于排序
  33. List<File>fileList=newArrayList<File>(Arrays.asList(fileArray));
  34. Collections.sort(fileList,newComparator<File>(){
  35. &nb
我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved