使用web uploder 与servlet实现分片上传文件(一)--前端实现

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

实现基本思路:

前端对文件进行分片,上传分片文件到服务器,服务器根据标识合并相关的文件。最终实现文件的上传。

前端实现

  • 简单页面实现
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>文件上传</title>
    <link ref="stylesheet" type="text/css" href="./webuploader-0.1.5/webuploader.css">
    <script type="text/javascript" src="./js/jquery.js"></script>
    <script type="text/javascript" src="./webuploader-0.1.5/webuploader.min.js"></script>
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="./bootstrap-4.3.1-dist/css/bootstrap.min.css">
    <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script> -->
    <script src="./bootstrap-4.3.1-dist/js/bootstrap.min.js"></script>
    <style type="text/css">
        .modal-header {
            padding: 0;
        }

        /*.modal-content{border-radius: 0;}*/
        .modal-dialog .close {
            position: absolute;
            top: 10px;
            right: 15px;
        }

        .modal-dialog h3 {
            font-size: 14px;
            height: 42px;
            line-height: 42px;
            margin: 0;
            padding: 0 80px 0 20px;
        }

        .modal-dialog label {
            font-weight: 400;
        }

        .tips {
            line-height: 34px;
            font-size: 13px;
        }

        .tips span {
            color: red;
        }

        @media (min-width: 1180px) {

            /*模态框-距顶部距离*/
            .modal-dialog {
                margin-top: 100px;
            }

            .col-sm-6 {
                padding-left: 0;
                padding-right: 0;
            }

        }

        .modal-body {
            font-size: 16px;
        }
    </style>
    <script src="./js/app_upload.js"></script>
</head>

<body>
    <!--模态框-->
    <div class="modal-dialog ">
        <div class="modal-content">
         
            <form class="" autocomplete="off" action="" disabled>
                <div class="modal-header">
                    <h3>文件上传</h3>
                </div>
                <div class="modal-body">
                     <div class="form-group row">
                        <label for="add_app" class="col-sm-3">应用文件:</label>
                        <input id="add_app" type="file" class="file  col-sm-8">
                        <div id="picker" class="col-sm-8">选择文件</div>
                    </div>
                    <div class="form-group row">
                            <button id="startUpload" type="button" onclick="start()" class="btn btn-primary   btn-sm">开始上传</button>
                            <button id="resetUpload" type="button" onclick="start()" class="btn btn-primary   btn-sm">开始上传</button>
                         <div id="currentInfo" class="col-sm-8" >
                            <strong></strong>
                        </div> 
                    </div>
                </div>
                <!-- 进度条 -->
                <div class="progress">
                    <div id="progressLength" class="progress-bar bg-success progress-bar-striped progress-bar-animated"
                        style="width:0%">0%</div>
                </div>

            </form>
        </div>
    </div>
</body>

</html>

基本效果:


image.png
  • 相关的js
var WSDL = "PublicTransferLoginService?wsdl";
var SOAP_XMLNS = '"http://service.dpns.com"';
var uploader;
$(document).ready(function () {
    var fileName;
    var fileMd5;
    //监听分块上传过程中的三个时间点
    WebUploader.Uploader.register({
        "before-send-file": "beforeSendFile",
        "before-send": "beforeSend",
        "after-send-file": "afterSendFile",
    }, {
            //时间点1 所有分块上传之前调用此函数
            beforeSendFile: function (file) {
                fileName = file.name;
                var deferred = WebUploader.Deferred();
                //1.使用md5计算文件的唯一标识,用于断点续传
                (new WebUploader.Uploader()).md5File(file, 0, 10 * 1024 * 1024)
                    .progress(function (percenttage) {
                        $("#item1").find("p.state").text("正在读取文件信息...");
                    })
                    .then(function (val) {
                        fileMd5 = val;
                        $("#item1").find("p.state").text("成功读取文件信息");
                        //获取文件信息后进入下一步
                        deferred.resolve();
                    });

                //调用 deferred.resolve();无效
                return deferred.promise();
            },
            //时间点2:如果有分块上传,则每个分块上传之前调用此函数    
            beforeSend: function (block, file) {
                console.log("分块" + fileName.replace(/.+\./, ""));
                var deferred = WebUploader.Deferred();

                $.ajax({
                    type: "POST",
                    url: "http://localhost:8686/MergeFile?action=checChunk",
                    data: {
                        action: "checChunk",
                        //文件唯一标记    
                        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 () {
                console.log("合并");
                //如果分块上传成功,则通知后台合并分块    
                $.ajax({
                    type: "POST",
                    url: "http://localhost:8686/MergeFile?action=mergeChunks",
                    data: {
                        fileMd5: fileMd5,
                    },
                    success: function (response) {
                        console.log(response);
                        alert("上传完成");
                    }
                });
            }
        });

    uploader = WebUploader.create({
        // swf文件路径    
        swf: '<%=basePath%>js/webuploader-0.1.5/Uploader.swf',
        // 文件接收服务端。    
        server: 'http://localhost:8686/FileUpLoad',
        // 选择文件的按钮。可选。    
        // 内部根据当前运行是创建,可能是input元素,也可能是flash.    
        pick: {
            id: '#picker',
            //这个id是你要点击上传文件的id,自己设置就好</span>    
            multiple: true
        },
        // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!    
        resize: true,
        auto: false,
        //上传并发数  
        threads: 5,
        //开启分片上传    
        chunked: true,
        chunkSize: 10 * 1024 * 1024,

        /* accept: {   
        //限制上传文件为MP4   
            extensions: 'mp4',   
            mimeTypes: 'video/mp4',   
        }   */
    });


    // 当有文件被添加进队列的时候    
    uploader.on('fileQueued', function (file) {
        $("#currentInfo").text("等待上传...");   
    });

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


    uploader.on('uploadSuccess', function (file) {
        // $( '#'+file.id ).find('p.state').text('上传完成');
        $("#currentInfo").text('上传完成');
        $("#currentInfo").css("color", "green");
    });

    uploader.on('uploadError', function (file) {
        // $( '#'+file.id ).find('p.state').text('上传出错'); 
        $("#currentInfo").text('上传出错,重新上传');
        $("#currentInfo").css("color", "red");
        //被锁的输入框打开
    });

    uploader.on('uploadComplete', function (file) { //上传完成移除进度条,进度条隐藏

        
    });

    $("#picker").hide();   //隐藏picker,并且不占用位置 
});

//开始上传
function start() {
    $("#myFieldset").disabled=true;
    //开始上传时,禁止修改form表单的值
    var filesList = $('#add_app').prop('files');
    uploader.addFiles(filesList); //将文件添加到uploader中  
    console.log(uploader.getFiles()[0]);
    var files = uploader.getFiles();
    if (files.length > 1) {
        // alert("只允许上传一个文件");
        $("#currentInfo").text('只允许上传一个文件');
        $("#currentInfo").css("color", "red");
        return;
    }
    uploader.upload();
}

//停止上传   
function stop() {
    uploader.stop(true);
    // $('#btn').attr("onclick","start()");    
    // $('#btn').text("继续上传"); 
}

function reset(){
    window.location.reload();
}

以上代码上传时,创建了三个时间点,在不同的时间点做相应的操作。并且调用了后端两个servlet.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,185评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,652评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,524评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,339评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,387评论 6 391
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,287评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,130评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,985评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,420评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,617评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,779评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,477评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,088评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,716评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,857评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,876评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,700评论 2 354