【学习笔记】SpringMvc+WebUploader整合处理

前一篇为首次处理后的学习,然后因所用的地方较多,且准备把上传的方法整合到表单页面中去,因此进行了抽象工作。
【学习笔记】WebUploader+SpringMVC的实现方式

因为要抽象,首先要把目前想要抽象的信息都整理出来
目前我整理了一份追加的js用来抽象script的存放
以下为自身抽象的webuploader.extend.js中的内容【内容略做修改,不影响使用】


/**
 * 根据传递的时间转换为yyyy-MM-dd hh:mm:ss
 * 
 * @param fmt  要转换的日期,如new Date()
 * 
 */
Date.prototype.format = function(fmt) { 
    var o = { 
       "M+" : this.getMonth()+1,                 //月份 
       "d+" : this.getDate(),                    //日 
       "h+" : this.getHours(),                   //小时 
       "m+" : this.getMinutes(),                 //分 
       "s+" : this.getSeconds(),                 //秒 
       "q+" : Math.floor((this.getMonth()+3)/3), //季度 
       "S"  : this.getMilliseconds()             //毫秒 
   }; 
   if(/(y+)/.test(fmt)) {
           fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length)); 
   }
    for(var k in o) {
       if(new RegExp("("+ k +")").test(fmt)){
            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
        }
    }
   return fmt; 
};


/**
 * 根据传递的页面元素对象,进行遮罩的处理
 * 
 * @param uploadbg 遮罩层div
 * 
 * @param uploadshow 遮罩层中显示文件上传信息的div
 * 
 */
function showdiv(uploadbg,uploadshow) {    
    $('#' + uploadbg).css("display","block");
    $('#' + uploadshow).css("display","block");
}
function hidediv(uploadbg,uploadshow) {
    $('#' + uploadbg).css("display","none");
    $('#' + uploadshow).css("display","none");
}

/**
 * 根据传递的值,进行WebUploader容器对象的生成
 * 
 * @param picker 放置文件的的DIV id
 * 
 * @param uploadParamsObj  需要传递的信息集合 
 * 主要包含   var uploadParams = {
                context: contextInfo, //此处为项目的全部地址 必须
                list : 'thelist', //上传文件的位置 必须
                fileSize : '', //文件的大小 必须
                nowDate : '', //文件上传的时间 必须
                auto : true, //是否自动上传
                fileNumLimit: 1, //上传文件的个数
                threads:3, //开启的上传文件并发数量
                chunked: true, //是否开启分片上传
                chunkSize: 10 * 1024 * 1024, //分片上传的大小,默认为10M
                fileSizeLimit : 50 * 1024 * 1024,  //最大上传文件的大小,默认为50M
                fileSizeLimitCN : '50M', //最大上传文件的大小中文提示,默认为50M
                uploadbg : 'uploadbg', //遮罩层div  必须
                uploadshow : 'uploadshow', //遮罩层中显示文件上传信息的div  必须
                waitUpload : 'waitUpload', //显示上传时的提示信息 必须
                progressUpload : 'progressUpload', //显示上传时的进度条信息 必须
                tableName : 'FILE_TABLE', // 上传附件的表名 必须
                realFileName : 'realName', //上传附件的真实存储名称ID 必须
                oldFileName : 'fileName' //上传文件的原始名称ID 必须
            };
 * 
 */
function uploadObj(picker,uploadParamsObj){

    var $list = $('#'+uploadParams.list);
    var $waitUpload = $('#'+uploadParams.waitUpload);
    var $progressUpload = $('#'+uploadParams.progressUpload);

    var uploader = WebUploader.create({
        swf: '/script/Uploader.swf',// swf文件路径
        server: uploadParams.context+'/webuploader/uploadFile',// 文件接收后台路径。
        pick: {
                   id: '#'+picker, //放置文件的ID,需传递值
                   name:"multiFile",  //定义file的name属性,还是要和fileVal 配合使用。不建议修改
                   label: '选择文件',
                   multiple:false  //默认为true,true表示可以多选文件,HTML5的属性
              },
        formData: {//传递参数使用
            "status":"file"
        },
        fileVal:'multiFile',//这个和后台的获取有关,不建议修改
        resize: false,
        auto: uploadParamsObj.auto != undefined ? uploadParamsObj.auto : true,//是否自动上传 ,true为自动上传,false为手动上传
        threads:uploadParamsObj.threads != undefined ? uploadParamsObj.threads : 3,//上传并发数。允许同时最大上传进程数。建议使用3,最大不能超过6
        chunked: uploadParamsObj.chunked != undefined ? uploadParamsObj.chunked : true,  //分片处理
        chunkSize: uploadParamsObj.chunkSize != undefined ? uploadParamsObj.chunkSize : 10 * 1024 * 1024, //每片10M
        fileNumLimit:1,//上传的文件总数  
        disableGlobalDnd: true // 禁掉全局的拖拽功能。这样不会出现图片拖进页面的时候,把图片打开。  
    });

    //当有文件添加进来的时候
    uploader.on( 'fileQueued', function( file ) {
        uploadParams.fileSize = file.size;
        var timestampnow = Date.parse(new Date());
        timestampnow = timestampnow / 1000;
        uploadParams.nowDate = timestampnow;
        $list.append( '<div id="' + file.id + '" class="item" style="display:inline">' +
            '<h4 class="info" style="display:inline">' + file.name + '</h4>&nbsp;&nbsp;' +
            '<div id=\'deleBut_'+file.id+'\' onclick="deleFile(\''+file.id+'\');" class="uploadbutton">移除</div>' +
        '</div>' );
        showdiv(uploadParamsObj.uploadbg,uploadParamsObj.uploadshow);
    });

    //当某个文件的分块在发送前触发,主要用来询问是否要添加附带参数,大文件在开起分片上传的前提下此事件可能会触发多次。
    uploader.on('uploadBeforeSend', function (obj, data, headers) {
        data.nowDate = uploadParams.nowDate;
        data.fileSize = uploadParams.fileSize;
        data.tableName = uploadParams.tableName;
    });

    //文件上传过程中创建进度条实时显示。
    uploader.on( 'uploadProgress', function( file, percentage ) {
        $waitUpload.text('正在上传,在此期间不要做其他操作,请耐心等待...');
        $progressUpload.css( 'width', percentage * 100 + '%' );
        $progressUpload.text((percentage * 100).toFixed(2) + '%');
    });

    //完成上传完了,成功或者失败,先删除进度条。
    uploader.on( 'uploadComplete', function( file ) {
        $('#'+picker).hide();
        hidediv(uploadParamsObj.uploadbg,uploadParamsObj.uploadshow);
    });

    // 文件上传成功,给item添加成功class, 用样式标记上传成功。
    uploader.on( 'uploadSuccess', function( file ,response  ) {
        $('#'+uploadParams.realFileName).val(response.realname);
        $('#'+uploadParams.oldFileName).val(response.fileSysName);
        $waitUpload.text('上传成功,正在合并文件,请耐心等待...');
    });

    // 文件上传失败,显示上传出错。
    uploader.on( 'uploadError', function( file ) {
        $waitUpload.text('上传失败,请移除文件后重新尝试上传...');
    });

    uploader.on( 'beforeFileQueued', function( file ) {
        var fileSizeLimit = uploadParams.fileSizeLimit;
        if(file.size > fileSizeLimit){
            if(uploadParamsObj.fileSizeLimitCN != undefined){
                alert('文件超出'+uploadParams.fileSizeLimitCN+',无法上传');
            } else {
                alert('文件超出50M,无法上传');
            }
            return false;
        } else {
            return true;
        }
    });

    return uploader;
}

下面为实现上传功能的前端jsp代码

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="c.tld" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>  
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="<c:url value="/scripts/jquery-1.9.1.js"/>"></script>
<!--引入CSS-->
<link rel="stylesheet" href="<c:url value="/styles/webuploader.css"/>" type="text/css" />
<!--引入JS-->
<script type="text/javascript" src="<c:url value="/scripts/webuploader.js"/>"></script>

<script type="text/javascript" src="<c:url value="/scripts/webuploader.extend.js"/>"></script>

</head>
<body>
<div id="uploader" class="wu-example">
    <div class="btns">
        <div id="picker" style="display:inline"></div>&nbsp;&nbsp;<div id="ctlBtn" class="uploadbutton" >上传</div>
        &nbsp;&nbsp;<div id="thelist" class="uploader-list"></div>
    </div>
    <div id="uploadbg" class='uploadbg'></div>
    <div id="uploadshow" class='uploadshow'>
        <font color='#EE7621'><label class="state" id="waitUpload">等待上传...</label></font>
        <div class="progress"  style="position: absolute;height:30px;width:300px;">
            <p id="progressUpload" style="top:0px;position: absolute;transform: translate(0%,0%);font-size: 10px;height:15px;width:0px;background-color:#E0FFFF;text-align:center">0%</p>
        </div>
    </div>
</div>

<script type="text/javascript">

//初始化Web Uploader
var contextInfo = 'http://'+'${header["host"]}'+'${pageContext.request.contextPath}';
var uploadParams = {
        context: contextInfo, //此处为项目的全部地址
        list : 'thelist', //上传文件的位置
        fileSize : '', //文件的大小
        nowDate : '', //文件上传的时间
        auto : true, //是否自动上传
        fileNumLimit: 1, //上传文件的个数
        threads:3, //开启的上传文件并发数量
        chunked: true, //是否开启分片上传
        chunkSize: 10 * 1024 * 1024, //分片上传的大小,默认为10M
        fileSizeLimit : 50 * 1024 * 1024,  //最大上传文件的大小,默认为50M
        fileSizeLimitCN : '50M', //最大上传文件的大小中文提示,默认为50M
        uploadbg : 'uploadbg', //遮罩层div
        uploadshow : 'uploadshow', //遮罩层中显示文件上传信息的div
        waitUpload : 'waitUpload', //显示上传时的提示信息
        progressUpload : 'progressUpload', //显示上传时的进度条信息
        tableName : 'FileTable', // 上传附件的表名
        realFileName : 'realName', //上传附件的真实存储名称ID
        oldFileName : 'fileName' //上传文件的原始名称ID
    };
var uploader = uploadObj('picker',uploadParams);

/**
 * 移除文件使用,未删除后台已上传文件,可以自行后续修改,添加ajax方法即可
 * 
 * @param fileId 上传的文件ID,在一个页面中自动生成,唯一
 * 
 * @param uploader 上传容器对象
 * 
 * 删除文件这个,抽象时发现部分信息传递出现问题,因此未放到抽象js中
 * 
 */
function deleFile(fileId) {
   uploader.removeFile(fileId,true);
   $('#'+fileId).remove();
   $('#picker').show();
};


</script>
</body>
</html>

在使用时,添加了自己使用的css样式,目前直接在原webuploader.css中添加

.webuploader-container {
    position: relative;
}
.webuploader-element-invisible {
    position: absolute !important;
    clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
    clip: rect(1px,1px,1px,1px);
}
.webuploader-pick {
    position: relative;
    display: inline-block;
    cursor: pointer;
    background: #00b7ee;
    padding: 4px 6px;
    color: #fff;
    text-align: center;
    border-radius: 3px;
    overflow: hidden;
}
.webuploader-pick-hover {
    background: #00a2d4;
}

.webuploader-pick-disable {
    opacity: 0.6;
    pointer-events:none;
}


/* 自身添加的样式表 */

.uploadbutton {
    position: relative;
    display: inline-block;
    cursor: pointer;
    background: #00b7ee;
    padding: 4px 6px;
    color: #fff;
    text-align: center;
    border-radius: 3px;
    overflow: hidden;
}

.uploadbutton-hover {
    background: #00a2d4;
}

.uploadbutton-disable {
    opacity: 0.6;
    pointer-events:none;
}

.uploadbg {
    display: none;
    position: absolute;
    top: 0%;
    left: 0%;
    width: 100%;
    height: 100%;
    background-color: #EBEBEB;
    z-index: 1001;
    -moz-opacity: 0.7;
    opacity: .70;
    filter: alpha(opacity = 70);
}

.uploadshow {
    display: none;
    position: absolute;
    top: 45%;
    left: 30%;
    width: 40%;
    height: 10%;
    padding: 8px;
    border: 0px solid #F1F1F1;
    background-color: #F1F1F1;
    z-index: 1002;
    overflow: auto;
}

上传的方法,和之前的版本相比未做大量改动

@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, String> uploadFile(HttpServletRequest request, HttpServletResponse response) throws Exception {
        Map<String, String> sMap = new HashMap<String, String>();
        try {  
            boolean isMultipart = ServletFileUpload.isMultipartContent(request);  
            if (isMultipart) {  
                FileItemFactory factory = new DiskFileItemFactory();  
                ServletFileUpload upload = new ServletFileUpload(factory);  

                // 得到所有的表单域,它们目前都被当作FileItem  
                List<FileItem> fileItems = upload.parseRequest(request);  

                String id = "";  
                // 如果大于1说明是分片处理  
                int chunks = 1;  
                int chunk = 0;  
                long fileSize = 0;
                long nowDate = 0;
                String tableName = "";
                FileItem tempFileItem = null;  

                for (FileItem fileItem : fileItems) {  
                    if (fileItem.getFieldName().equals("id")) {  
                        id = fileItem.getString();  
                    } else if (fileItem.getFieldName().equals("chunks")) {  
                        chunks = NumberUtils.toInt(fileItem.getString());  
                    } else if (fileItem.getFieldName().equals("chunk")) {  
                        chunk = NumberUtils.toInt(fileItem.getString());  
                    } else if (fileItem.getFieldName().equals("multiFile")) {  
                        tempFileItem = fileItem;  
                    } else if (fileItem.getFieldName().equals("fileSize")) {  
                        fileSize = NumberUtils.toLong(fileItem.getString());
                    } else if (fileItem.getFieldName().equals("tableName")) {  
                        tableName = fileItem.getString();
                    } else if (fileItem.getFieldName().equals("nowDate")) {  
                        nowDate = NumberUtils.toLong(fileItem.getString());
                    }
                }  

                String fileSysName = tempFileItem.getName();
                String realname = nowDate+fileSysName.substring(fileSysName.lastIndexOf("."));//转化后的文件名  
                sMap.put("fileSysName", fileSysName);
                sMap.put("realname", realname);
                //
                String realPath = Constants.ROOT_FILE_PATH;
                realPath = realPath + File.separator + tableName.toUpperCase() + File.separator;
                String filePath = realPath;//文件上传路径  

                // 临时目录用来存放所有分片文件  
                String tempFileDir = filePath + id + "_" + fileSize + "_" + nowDate;
                File parentFileDir = new File(tempFileDir);  
                if (!parentFileDir.exists()) {  
                    parentFileDir.mkdirs();  
                }  
                // 分片处理时,前台会多次调用上传接口,每次都会上传文件的一部分到后台  
                File tempPartFile = new File(parentFileDir, realname + "_" + chunk + ".part");  
                FileUtils.copyInputStreamToFile(tempFileItem.getInputStream(), tempPartFile);  

                // 是否全部上传完成  
                // 所有分片都存在才说明整个文件上传完成  
                boolean uploadDone = true;  
                for (int i = 0; i < chunks; i++) {  
                    File partFile = new File(parentFileDir, realname + "_" + i + ".part");  
                    if (!partFile.exists()) {  
                        uploadDone = false;  
                    }  
                }  
                // 所有分片文件都上传完成  
                // 将所有分片文件合并到一个文件中  
                if (uploadDone) {  
                    // 得到 destTempFile 就是最终的文件  
                    File destTempFile = new File(filePath, realname);  
                    for (int i = 0; i < chunks; i++) {
                        File partFile = new File(parentFileDir, realname + "_" + i + ".part");  
                        FileOutputStream destTempfos = new FileOutputStream(destTempFile, true);  
                        //遍历"所有分片文件"到"最终文件"中  
                        FileUtils.copyFile(partFile, destTempfos);  
                        destTempfos.close();  
                    }  
                    // 删除临时目录中的分片文件  
                    FileUtils.deleteDirectory(parentFileDir);  
                }
            }  
        } catch (Exception e) {  
            logger.error(e.getMessage(), e);  
        }
        return sMap;
    }

至此抽象功能完成,后续的就是和业务如何关联的问题了,目前是使用的是,返回的map中存放上传的文件信息,最后进行文件的数据保存处理,删除时,未做移除删除本地文件的功能,可以后续自行添加。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值