1、先将 webuploader-0.1.5.zip 这个文件下载下来:https://github.com/fex-team/webuploader/releases  
根据个人的需求放置自己需要的东西就行,全部放到项目里也可以,下面是我自己需要的东西:

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

1、jsp部分代码:
 
<script type="text/javascript">
        var fileMd5;
        //监听分块上传过程中的三个时间点
        WebUploader.Uploader.register({
        "before-send-file":"beforeSendFile",
        "before-send":"beforeSend",
        "after-send-file":"afterSendFile",
        },{
        //时间点1:所有分块进行上传之前调用此函数
        beforeSendFile:function(file){
        var deferred = WebUploader.Deferred();
        //1、计算文件的唯一标记,用于断点续传
        (new WebUploader.Uploader()).md5File(file,0,10*1024*1024)
        .progress(function(percentage){
        $('#item1').find("p.state").text("正在读取文件信息...");
        })
        .then(function(val){
        fileMd5=val;
        $('#item1').find("p.state").text("成功获取文件信息...");
        //获取文件信息后进入下一步
        deferred.resolve();
        });
        return deferred.promise();
        },
        //时间点2:如果有分块上传,则每个分块上传之前调用此函数
        beforeSend:function(block){
        var deferred = WebUploader.Deferred();
        $.ajax({
        type:"POST",
        url:"<%=basePath%>Video?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;
        deferred.resolve();
        return deferred.promise();
        },
        //时间点3:所有分块上传成功后调用此函数
        afterSendFile:function(){
        //如果分块上传成功,则通知后台合并分块
        $.ajax({
        type:"POST",
        url:"<%=basePath%>Video?action=mergeChunks",
        data:{
        fileMd5:fileMd5,
        },
        success:function(response){
        alert("上传成功");
                  var path = "uploads/"+fileMd5+".mp4";
                  $("#item1").attr("src",path);
        }
        });
        }
        });
        var uploader = WebUploader.create({
   // swf文件路径
   swf: '<%=basePath%>scripts/webuploader-0.1.5/Uploader.swf',
   // 文件接收服务端。
   server: '<%=basePath%>UploadVideo',
   // 选择文件的按钮。可选。
   // 内部根据当前运行是创建,可能是input元素,也可能是flash.
   pick: {id: '#add_video',   //这个id是你要点击上传文件的id,自己设置就好
   multiple:false},
   // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
   resize: true,
   auto:true,
   //开启分片上传
   chunked: true,
   chunkSize:10*1024*1024,
   accept: {
   //限制上传文件为MP4
            extensions: 'mp4',
            mimeTypes: 'video/mp4',
        }
});
        // 当有文件被添加进队列的时候
uploader.on( 'fileQueued', function( file ) {
$('#item1').empty();
   $('#item1').html('<div id="' + file.id + '" class="item">'+
    '<a class="upbtn" id="btn" onclick="stop()">[取消上传]</a>'+
    '<p class="info">' + file.name + '</p>' +
       '<p class="state">等待上传...</p></div>'
   );
});
// 文件上传过程中创建进度条实时显示。
uploader.on( 'uploadProgress', function( file, percentage ) {
   $('#item1').find('p.state').text('上传中 '+Math.round(percentage * 100) + '%');
});
uploader.on( 'uploadSuccess', function( file ) {
   $( '#'+file.id ).find('p.state').text('已上传');
});
uploader.on( 'uploadError', function( file ) {
   $( '#'+file.id ).find('p.state').text('上传出错');
});
uploader.on( 'uploadComplete', function( file ) {
   $( '#'+file.id ).find('.progress').fadeOut();
});
      function start(){
uploader.upload();
$('#btn').attr("onclick","stop()");
$('#btn').text("取消上传");
}
function stop(){
uploader.stop(true);
$('#btn').attr("onclick","start()");
$('#btn').text("继续上传");
}
    </script>
//这个id是你要点击上传文件的id,自己设置就好
   multiple:false},
   // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
   resize: true,
   auto:true,
   //开启分片上传
   chunked: true,
   chunkSize:10*1024*1024,
   
   accept: {
   //限制上传文件为MP4
            extensions: 'mp4',
            mimeTypes: 'video/mp4',
        }
});
       
        // 当有文件被添加进队列的时候
uploader.on( 'fileQueued', function( file ) {

$('#item1').empty();
   $('#item1').html('<div id="' + file.id + '" class="item">'+
    '<a class="upbtn" id="btn" onclick="stop()">[取消上传]</a>'+
    '<p class="info">' + file.name + '</p>' +
       '<p class="state">等待上传...</p></div>'
   );
});

// 文件上传过程中创建进度条实时显示。
uploader.on( 'uploadProgress', function( file, percentage ) {
   $('#item1').find('p.state').text('上传中 '+Math.round(percentage * 100) + '%');
});

uploader.on( 'uploadSuccess', function( file ) {
   $( '#'+file.id ).find('p.state').text('已上传');
});

uploader.on( 'uploadError', function( file ) {
   $( '#'+file.id ).find('p.state').text('上传出错');
});

uploader.on( 'uploadComplete', function( file ) {
   $( '#'+file.id ).find('.progress').fadeOut();
});
      
      function start(){
uploader.upload();
$('#btn').attr("onclick","stop()");
$('#btn').text("取消上传");
}

function stop(){
uploader.stop(true);
$('#btn').attr("onclick","start()");
$('#btn').text("继续上传");
}
        
    </script>
 
 
 
2、servlet部分代码:

servlet部分需要两个servlet,一个用于接收分块文件,一个用于合并分块成一个文件:
1、接收分块servlet代码:
 
@SuppressWarnings("serial")
public class UploadVideo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
super.doGet(req, resp);
doPost(req, resp);
}
    @SuppressWarnings("unchecked")
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
    DiskFileItemFactory factory = new DiskFileItemFactory();
    ServletFileUpload sfu = new ServletFileUpload(factory);
    sfu.setHeaderEncoding("utf-8");
    String savePath = this.getServletConfig().getServletContext()
                .getRealPath("");
        String folad = "uploads";
        savePath = savePath + "\\"+folad+"\\";
    String fileMd5 = null;
    String chunk = null;
    try {
List<FileItem> items = sfu.parseRequest(request);
for(FileItem item:items){
if(item.isFormField()){
String fieldName = item.getFieldName();
if(fieldName.equals("fileMd5")){
fileMd5 = item.getString("utf-8");
}
if(fieldName.equals("chunk")){
chunk = item.getString("utf-8");
}
}else{
File file = new File(savePath+"/"+fileMd5);
if(!file.exists()){
file.mkdir();
}
File chunkFile = new File(savePath+"/"+fileMd5+"/"+chunk);
FileUtils.copyInputStreamToFile(item.getInputStream(), chunkFile);
}
}
} catch (FileUploadException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
    }
}
 
 
 
2、合并分块servlet代码:
 
@SuppressWarnings("serial")
public class Video extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
super.doGet(request, response);
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String savePath = this.getServletConfig().getServletContext()
                .getRealPath("");
        String folad = "uploads";
        savePath = savePath + "\\"+folad+"\\";
String action = request.getParameter("action");
if(action.equals("mergeChunks")){
//合并文件
//需要合并的文件的目录标记
String fileMd5 = request.getParameter("fileMd5");
//读取目录里的所有文件
File f = new File(savePath+"/"+fileMd5);
File[] fileArray = f.listFiles(new FileFilter(){
//排除目录只要文件
@Override
public boolean accept(File pathname) {
// TODO Auto-generated method stub
if(pathname.isDirectory()){
return false;
}
return true;
}
});
//转成集合,便于排序
List<File> fileList = new ArrayList<File>(Arrays.asList(fileArray));
Collections.sort(fileList,new Comparator<File>() {
@Override
public int compare(File o1, File o2) {
// TODO Auto-generated method stub
if(Integer.parseInt(o1.getName()) < Integer.parseInt(o2.getName())){
return -1;
}
return 1;
}
});
//UUID.randomUUID().toString()-->随机名
File outputFile = new File(savePath+"/"+fileMd5+".mp4");
//创建文件
outputFile.createNewFile();
//输出流
FileChannel outChnnel = new FileOutputStream(outputFile).getChannel();
//合并
FileChannel inChannel;
for(File file : fileList){
inChannel = new FileInputStream(file).getChannel();
inChannel.transferTo(0, inChannel.size(), outChnnel);
inChannel.close();
//删除分片
file.delete();
}
outChnnel.close();
//清除文件夹
File tempFile = new File(savePath+"/"+fileMd5);
if(tempFile.isDirectory() && tempFile.exists()){
tempFile.delete();
}
System.out.println("合并成功");
}else if(action.equals("checkChunk")){
//检查当前分块是否上传成功
String fileMd5 = request.getParameter("fileMd5");
String chunk = request.getParameter("chunk");
String chunkSize = request.getParameter("chunkSize");
File checkFile = new File(savePath+"/"+fileMd5+"/"+chunk);
response.setContentType("text/html;charset=utf-8");
//检查文件是否存在,且大小是否一致
if(checkFile.exists() && checkFile.length()==Integer.parseInt(chunkSize)){
//上传过
response.getWriter().write("{\"ifExist\":1}");
}else{
//没有上传过
response.getWriter().write("{\"ifExist\":0}");
}
}
}
}
 
 
 
至此,大文件上传的分块和断点就ok了,这也只是我自己的项目需求编写的,这个框架还涵盖很多的内容和功能,需要你自己去研究了,不过都不是很难,你也可以去修改它的css和js文件根据自己的需求。
详细的配置信息可以参考我写的这篇文章:http://blog.ncmem.com/wordpress/2019/08/28/java%E6%89%B9%E9%87%8F%E4%B8%8B%E8%BD%BD/

B/S大文件下载+断点续传的更多相关文章

  1. php大文件下载+断点续传

    如果我们的网站提供文件下载的服务,那么通常我们都希望下载可以断点续传(Resumable Download),也就是说用户可以暂停下载,并在未来的某个时间从暂停处继续下载,而不必重新下载整个文件. 通 ...

  2. web大文件下载+断点续传

    实现原理(1)首先获得下载文件的长度,然后设置本地文件的长度.(2)根据文件长度和线程数计算每条线程下载的数据长度和下载位置.如:文件的长度为6M,线程数为3,那么,每条线程下载的数据长度为2M,每条 ...

  3. jsp大文件下载+断点续传

    以多线程.断点续传方式下载文件,经常出现下载下来的文件大小和服务端一致,但是却无法正常打开的现象,搞了很久,贴下我的实现方式,请各位多多指教思路:1.将下载文件的处理放在自定义的线程类中,每下载一个文 ...

  4. java大文件下载+断点续传

    java两台服务器之间,大文件上传(续传),采用了Socket通信机制以及JavaIO流两个技术点,具体思路如下: 实现思路:1.服:利用ServerSocket搭建服务器,开启相应端口,进行长连接操 ...

  5. iOS开发之网络编程--使用NSURLConnection实现大文件下载

    主要思路(实现下载数据分段写入缓存中) 1.使用NSURLConnectionDataDelegate以及代理方法.2.在成功获取响应的代理方法中,获得沙盒全路径,并在该路径下创建空文件和文件句柄.3 ...

  6. iOS开发-大文件下载与断点下载思路

    大文件下载方案一:利用NSURLConnection和它的代理方法,及NSFileHandle(iOS9后不建议使用)相关变量: @property (nonatomic,strong) NSFile ...

  7. java web 大文件下载

    泽优大文件下载产品测试 泽优大文件下载控件down2,基于php开发环境测试. 开发环境:HBuilder 服务器:wamp64 数据库:mysql 可视化数据库编辑工具:Navicat Premiu ...

  8. IOS-网络(大文件下载)

    一.不合理方式 // // ViewController.m // IOS_0131_大文件下载 // // Created by ma c on 16/1/31. // Copyright © 20 ...

  9. 【nginx】记录nginx+php-fpm实现大文件下载排坑的过程

    先上一段代码,支持大文件下载和断点续传,代码来源互联网. set_time_limit(0); // 省略取文件路径的过程,这里直接是文件完整路径 $filePath = get_save_path( ...

随机推荐

  1. 【js】什么是函数节流与函数去抖

    函数节流 意思:节省流量,不会一直访问. | 指定时间内不执行,指定时间后执行. | 一段时间内只执行一次 场景: 比如控制游戏人物攻击,时间内就算按得很快,也只能砍一刀,过后才能砍第二刀. 搜索引擎 ...

  2. centos7:Kafka集群安装

    解压文件到安装目录 tar -zxvf kafka_2.10-0.10.2.1.tgz 1.进入目录 cd kafka_2.10-0.10.2.1 mkdir logs cd config cp se ...

  3. 使用logstash收集java、nginx、系统等常见日志

    目录 1.使用codec的multiline插件收集java日志... 1 2.收集nginx日志... 2 3.收集系统syslog日志... 3 4.使用fliter的grok模块收集mysql日 ...

  4. 十、Zabbix-自动关联模板

    之前的文章中,我们实现了自动注册,自动分组:并且创建了模板,监控项,触发器.为的就是能够实现主机自动被期望的监控项监控到.接下来我们只要能让自动注册的主机能够自动连接到我们设置好的模板,就可以实现自动 ...

  5. 为企业服务器配置RAID0、raid1、 raid10、raid5、raid6、等常见RAID

    RAID卡操作手册先从开机启动时如何进入管理界面开始介绍: 1)当机器开启后,显示器出现阵列卡检测信息时,会提示用户是否要进入管理界面对阵列卡进行操作,此时按下Ctrl + H 即可,如下图 2)按下 ...

  6. [Web 前端] 032 vue 初识

    目录 0. 先下载 1. 先写个轮廓 2. 牛刀小试 2.1 例子 1 2.2 例子 2 3. 模板语法 上例子 4. 文本指令 上例子 5. 属性操作 上例子 6. 样式操作 上例子 类名的操作 s ...

  7. [Python3] 004 字符串的基本使用

    目录 1. 字符串简介 1.1 作用 1.2 注意点 2. 使用方式 2.1 用引号括起来 少废话,上例子 2.2 单.双引号可以"轮换交替" 少废话,上例子 3. 转义字符 3. ...

  8. 四:JVM调优原理与常见异常处理方案

    在jvm调优之前,我们必须先了解jvm的内存模型与GC回收机制,这些在我前面的文章里面有介绍!接下来我们通过一个案例来调整jvm性能. 一测试案例: 1.1 编写demo import java.te ...

  9. #define 宏实现函数功能可能存在的问题

    #define 宏实现函数功能的问题 情形1 #define free_ptr(p) \ if(p) delete p; p = nullptr; 在调用free_ptr(p)的地方展开看这段代码: ...

  10. SpringBoot自定义配置步骤

    1. 在yml中填写自定义配置 ly: sms: accessKeyId: # 短信配置 accessKeySecret: signName: xx商城 # 签名名称 verifyCodeTempla ...