上传笔记【一】webUploader 多文件上传并保存数据库


项目:status2 spring hibernate


最近写了个模块,人员档案库,由于客户要求要实现多文件上传,所以苦逼的又要学习新的知识了,多文件上传已经实现了,所以在这里做个笔记。


1,首先到官网下载js,css,引入项目




jsp页面:


或将文件拖到这里,单个文件大小不超过2M,单次上传文件总大小不超过20M


下面是js:

(function( $ ){
    // 当domReady的时候开始初始化
    $(function() {
        var $wrap = $('#uploader'),
            // 图片容器
            $queue = $( '
    ' ) .appendTo( $wrap.find( '.queueList' ) ), // 状态栏,包括进度和控制按钮 $statusBar = $wrap.find( '.statusBar' ), // 文件总体选择信息。 $info = $statusBar.find( '.info' ), // 上传按钮 $upload = $wrap.find( '.uploadBtn' ), // 没选择文件之前的内容。 $placeHolder = $wrap.find( '.placeholder' ), $progress = $statusBar.find( '.progress' ).hide(), // 添加的文件数量 fileCount = 0, // 添加的文件总大小 fileSize = 0, // 所有文件的进度信息,key为file id percentages = {}, // 实例化 uploader = WebUploader.create({ pick: { id: '#filePicker', label: '点击选择文件', name:"multiFile" }, formData: { //这里可以向后台传自定义的参数比如 key:value }, dnd: '#dndArea', paste: '#uploader', swf: '../../js/webuploader/Uploader.swf',//引用Uploader.swf,去官网下载 fileVal:'multiFile', chunked: false, // 是否分片上传 chunkSize: 512 * 1024, server: 'http://localhost:8080/ctcst/archives_uploadInformation.action', //提交到服务器 //规定文件上传的格式 accept: { title: 'file', extensions: 'gif,jpg,jpeg,bmp,png', mimeTypes: 'image/*' }, // 禁掉全局的拖拽功能。这样不会出现图片拖进页面的时候,把图片打开。 disableGlobalDnd: true, fileNumLimit: 10, fileSizeLimit: 20 * 1024 * 1024, // 20 M fileSingleSizeLimit: 2 * 1024 * 1024 // 2 M }); // 拖拽时不接受 js, txt 文件。 uploader.on( 'dndAccept', function( items ) { var denied = false, len = items.length, i = 0, // 修改js类型 unAllowed = 'text/plain;application/javascript '; for ( ; i < len; i++ ) { // 如果在列表里面 if ( ~unAllowed.indexOf( items[ i ].type ) ) { denied = true; break; } } return !denied; }); // 添加“添加文件”的按钮, uploader.addButton({ id: '#filePicker2', label: '继续添加' }); uploader.on('ready', function() { window.uploader = uploader; }); // 上传失败触发 uploader.on('uploadError', function (file, reason) { console.log(file); console.log(reason); console.log('上传失败' + reason); }); //成功时触发 uploader.on('uploadSuccess', function (file, response) { console.log(file); console.log(response); console.log('上传成功' + response); }); // 文件上传后服务端响应,服务端处理失败返回false,调用uploadError事件 uploader.on('uploadAccept', function(obj, ret){ console.log(obj); console.log(ret); console.log('uploadAccept===执行了'); }); // 当有文件添加进来时执行,负责view的创建 function addFile( file ) { var $li = $( '
  • ' + '

    '+ '

    ' + file.name + '

    ' + '

    ' + '
  • ' ), $btns = $('
    ' + '删除' + '向右旋转' + '向左旋转
    ').appendTo( $li ), $prgress = $li.find('p.progress span'), $wrap = $li.find( 'p.imgWrap' ), $info = $('

    '), showError = function( code ) { switch( code ) { case 'exceed_size': text = '文件大小超出'; break; case 'interrupt': text = '上传暂停'; break; default: text = '上传失败,请重试'; break; } $info.text( text ).appendTo( $li ); }; if ( file.getStatus() === 'invalid' ) { showError( file.statusText ); } else { // @todo lazyload $wrap.text( '预览中' ); uploader.makeThumb( file, function( error, src ) { var img; if ( error ) { // 跟据文件类型显示对应缩略图 jpg,png直接预览 // gif,jpg,jpeg,bmp,png,zip,rar,pdf,xls,xlsx,doc,docx var fileExt = file.ext; switch (fileExt) { case 'zip': src = getadress() + '/csim/ctcst/archives/images/ZIP.jpg'; break; case 'xlsx': src = getadress() + '/csim/ctcst/archives/images/XLSX.png'; break; case 'rar': src = getadress() + '/csim/ctcst/archives/images/RAR.jpg'; break; case 'pdf': src = getadress() + '/csim/ctcst/archives/images/PDF.jpg'; break; case 'xls': src = getadress() + '/csim/ctcst/archives/images/XLS.png'; break; case 'doc': src = getadress() + '/csim/ctcst/archives/images/DOC.png'; break; case 'docx': src = getadress() + '/csim/ctcst/archives/images/DOCX.png'; break; default : $wrap.text( '文件格式不支持预览' ); return; } } if( isSupportBase64 ) { img = $(''); $wrap.empty().append( img ); } }, thumbnailWidth, thumbnailHeight ); percentages[ file.id ] = [ file.size, 0 ]; file.rotation = 0; } file.on('statuschange', function( cur, prev ) { if ( prev === 'progress' ) { $prgress.hide().width(0); } else if ( prev === 'queued' ) { //取消旋转删除div //$li.off( 'mouseenter mouseleave' ); //$btns.remove(); } // 成功 if ( cur === 'error' || cur === 'invalid' ) { //console.log( file.statusText ); showError( file.statusText ); percentages[ file.id ][ 1 ] = 1; } else if ( cur === 'interrupt' ) { showError( 'interrupt' ); } else if ( cur === 'queued' ) { percentages[ file.id ][ 1 ] = 0; } else if ( cur === 'progress' ) { $info.remove(); $prgress.css('display', 'block'); } else if ( cur === 'complete' ) { $li.append( '' ); } $li.removeClass( 'state-' + prev ).addClass( 'state-' + cur ); }); $li.on( 'mouseenter', function() { $btns.stop().animate({height: 30}); }); $li.on( 'mouseleave', function() { $btns.stop().animate({height: 0}); }); $btns.on( 'click', 'span', function() { var index = $(this).index(), deg; switch ( index ) { case 0: uploader.removeFile( file ); return; case 1: file.rotation += 90; break; case 2: file.rotation -= 90; break; } if ( supportTransition ) { deg = 'rotate(' + file.rotation + 'deg)'; $wrap.css({ '-webkit-transform': deg, '-mos-transform': deg, '-o-transform': deg, 'transform': deg }); } else { $wrap.css( 'filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation='+ (~~((file.rotation/90)%4 + 4)%4) +')'); } }); $li.appendTo( $queue ); } // 负责view的销毁 function removeFile( file ) { var $li = $('#'+file.id); delete percentages[ file.id ]; updateTotalProgress(); $li.off().find('.file-panel').off().end().remove(); } }); })( jQuery );


    后台接收数据如下:
    第一步:建一个vo类,用于接收前台传来的参数

    public class UploadImagesVo {
        private String id;
        //文件上传需要的参数
        private File multiFile[];
        private String multiFileFileName[];
    
         public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
        public File[] getMultiFile() {
            return multiFile;
        }
    
        public void setMultiFile(File[] multiFile) {
            this.multiFile = multiFile;
        }
    
        public String[] getMultiFileFileName() {
            return multiFileFileName;
        }
    
        public void setMultiFileFileName(String[] multiFileFileName) {
            this.multiFileFileName = multiFileFileName;
        }
    }

    第二步:创建一个实体类:


    Entity
    @Table(name = "PX_DA_UPLOAD_INFO")
    public class UploadInfromation {
        private String id;
        private String dataCategory;//资料类别 ,个人资料 班级资料
        private String type;//类型 如:培训详情,鉴定详情
        private String batchNo;//班级编号==属于哪个班级
        private String fileName;//重命名之后的文件名称
        private String uploadName;//文件原始名称
        private String fileId;//文件的唯一标识
        private String path;//文件全路径
        private String filePath;//文件所在路径
        private String jgNo; //上传文件机构编号
        private String idNumber; //个人身份证
        @Id
        @GeneratedValue(generator = "upload_info_uuid")
        @GenericGenerator(name = "upload_info_uuid", strategy = "uuid")
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getIdNumber() {
            return idNumber;
        }
    
        public void setIdNumber(String idNumber) {
            this.idNumber = idNumber;
        }
    
        public String getFileId() {
            return fileId;
        }
    
        public void setFileId(String fileId) {
            this.fileId = fileId;
        }
    
        public String getFilePath() {
            return filePath;
        }
    
        public void setFilePath(String filePath) {
            this.filePath = filePath;
        }
    
        public String getDataCategory() {
            return dataCategory;
        }
    
        public void setDataCategory(String dataCategory) {
            this.dataCategory = dataCategory;
        }
    
        public String getType() {
            return type;
        }
    
        public void setType(String type) {
            this.type = type;
        }
    
        public String getBatchNo() {
            return batchNo;
        }
    
        public void setBatchNo(String batchNo) {
            this.batchNo = batchNo;
        }
    
        public String getFileName() {
            return fileName;
        }
    
        public void setFileName(String fileName) {
            this.fileName = fileName;
        }
    
        public String getUploadName() {
            return uploadName;
        }
    
        public void setUploadName(String uploadName) {
            this.uploadName = uploadName;
        }
        public String getPath() {
            return path;
        }
    
        public void setPath(String path) {
            this.path = path;
        }
    
        public String getJgNo() {
            return jgNo;
        }
    
        public void setJgNo(String jgNo) {
            this.jgNo = jgNo;
        }
    }

    第三步:建一个action类:

    @SuppressWarnings("serial")
    public class ArchivesAction extends ActionSupport implements ModelDriven{
        private UploadImagesVo vo = new UploadImagesVo();
        private IUploadImagesService uploadService;
        /**
         * 上传信息
         */
        public void uploadInformation(){
            Json json = new Json();
            try {
                UploadInformVo up = uploadService.uploadInformations(vo);
                json.setObj(up);
                json.setSuccess(true);
            }catch (Exception e){
                e.printStackTrace();
                json.setMsg(e.getMessage());
            }
            writeJson(json);
        }
        /**
         * 写出json
         * @param object 任何类型
         */
        public void writeJson(Object object) {
            try {
                String json = JSON.toJSONStringWithDateFormat(object, "yyyy-MM-dd");
                ServletActionContext.getResponse().setContentType(
                        "text/html;charset=utf-8");
                ServletActionContext.getResponse().getWriter().write(json);
                ServletActionContext.getResponse().getWriter().flush();
                ServletActionContext.getResponse().getWriter().close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public IUploadImagesService getUploadService() {
            return uploadService;
        }
        @Resource
        public void setUploadService(IUploadImagesService uploadService) {
            this.uploadService = uploadService;
        }
    
        @Override
        public UploadImagesVo getModel() {
            return vo;
        }
    }

    第四步:创建一个Dao接口,既然要保存到数据库,那Dao层是必有得

    public interface IUploadInformDao extends IBaseDAO{
        
    }

    第五步:创建一个Dao并实现Dao接口

    @Component
    public class UploadInformDao extends BaseDAO  implements IUploadInformDao {
       
        
    }

    第六步:创建一个service的接口:

    public interface  IUploadImagesService {
    
        /**
         * 文件上传
         * @param vo
         * @throws Exception
         */
        public UploadInformVo uploadInformations(UploadImagesVo vo) throws Exception;
    
    }

    第七步:现在Entity,action,service接口,Dao都有已经创建好了,可以开始实现业务逻辑了,创建一个service层并实现接口


    @Component
    public class UploadImagesService   implements IUploadImagesService  {
        private IUploadInformDao uploadInformDao;
        /**
         * 文件上传
         * @param vo
         * @throws Exception
         */
        public UploadInformVo uploadInformations(UploadImagesVo  vo) throws Exception{
        		//取到当前登录的用户信息
                Users user = SecurityUser.getCurrentUserInfo();
                //生成MD5值
                String MD5 = getMd5ByFile(vo.getMultiFile()[0]);
                //上传的文件名
                String fileName =MD5+vo.getMultiFileFileName()[0].substring(vo.getMultiFileFileName()[0].lastIndexOf("."));
                //指定输出的路径,从项目的配置文件里读取
                PropertiesUtil propertiesu = PropertiesUtil.getInstance();
                String path = propertiesu.getKeyValue("archivesPath");
                if(!StringUtil.isNull(vo.getLx())){
                    path+= File.separatorChar+vo.getLx();
                }
                if(!StringUtil.isNull(vo.getTypes())){
                    path+=File.separatorChar+vo.getTypes();
                }
                if(!StringUtil.isNull(vo.getBatchNo())){
                    path+=File.separatorChar+vo.getBatchNo();
                }
                if(!StringUtil.isNull(vo.getIdNumber())){
                    path+=File.separatorChar+vo.getIdNumber();
                }
                //查询上传的图片是否已经上传过了,每个图片的MD5是唯一的
                UploadInfromation upload = new UploadInfromation();
                upload.setFilePath(path);
                upload.setFileId(MD5);
                List list = uploadInformDao.findByProperties(upload);
                if(list.size() > 0){
                    throw  new Exception(vo.getMultiFileFileName()[0]+" 文件在"+path+" 这个路径中已存在");
                }
                //取到文件并调用outFile方法写到指定的路径
                File file = vo.getMultiFile()[0];
                 outFile(path, file,fileName);
    
                 //然后把数据保存到数据库	
                if(!StringUtil.isNull(vo.getBatchNo())){
                    upload.setBatchNo(vo.getBatchNo());
                }
                if(!StringUtil.isNull(vo.getIdNumber())){
                    upload.setIdNumber(vo.getIdNumber());
                }
                upload.setDataCategory(vo.getLx());
                upload.setType(vo.getTypes());
                upload.setFileName(fileName);
                upload.setUploadName(vo.getMultiFileFileName()[0]);
                String filePath = path + File.separatorChar +fileName;
                upload.setPath(filePath);
                upload.setJgNo(user.getUnitId());
                uploadInformDao.save(upload);
    
                //通过写出去图片的路径生成Base64编码,并用vo返回到jsp页面展示
                String str = imageToBase64(upload.getPath());
                UploadInformVo vov = new UploadInformVo();
                BeanUtils.copyProperties(upload,vov);
                String s = vo.getMultiFileFileName()[0].substring(vo.getMultiFileFileName()[0].indexOf(".")+1,vo.getMultiFileFileName()[0].length());
                String src = "data:image/"+s+";base64,"+str;
                vov.setBase64(src);
            return vov;
        }
    
        /**
         * 生成md5
         * @param file 图片文件
         * @return MD5值
         * @throws FileNotFoundException
         */
        private  String getMd5ByFile(File file) throws FileNotFoundException {
            String value = null;
            FileInputStream in = new FileInputStream(file);
            try {
                MappedByteBuffer byteBuffer = in.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length());
                MessageDigest md5 = MessageDigest.getInstance("MD5");
                md5.update(byteBuffer);
                BigInteger bi = new BigInteger(1, md5.digest());
                value = bi.toString(16);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if(null != in) {
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return value;
        }
    
        /**
         * 通过文件路径将文件转成Base64编码
         * @param path 文件路径
         * @return base64结果
         */
        private String imageToBase64(String path) {
            // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理
            byte[] data = null;
            // 读取图片字节数组
            try {
                InputStream in = new FileInputStream(path);
                data = new byte[in.available()];
                in.read(data);
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 对字节数组Base64编码
            BASE64Encoder encoder = new BASE64Encoder();
            return encoder.encode(data);// 返回Base64编码过的字节数组字符串
        }
    
        /**
         * 指定的地方写出文件
         * @param outPath 文件路径
         * @param tempFile 文件
         * @param fileName 文件名
         * @throws IOException 错误异常
         */
        private void outFile(String outPath,File tempFile,String fileName) throws IOException {
            RandomAccessFile raFile = null;
            BufferedInputStream inputStream=null;
            try{
                File dirFile = new File(outPath);
                if(!dirFile.exists()) {
                    dirFile.mkdirs();
                }
                File outFile = new File(outPath + File.separatorChar +fileName);
                raFile = new RandomAccessFile(outFile, "rw");
                raFile.seek(raFile.length());
                inputStream = new BufferedInputStream(new FileInputStream(tempFile));
                byte[] buf = new byte[1024];
                int length = 0;
                while ((length = inputStream.read(buf)) != -1) {
                    raFile.write(buf, 0, length);
                }
            }catch(Exception e){
                throw new IOException(e.getMessage());
            }finally{
                try {
                    if (inputStream != null) {
                        inputStream.close();
                    }
                    if (raFile != null) {
                        raFile.close();
                    }
                }catch(Exception e){
                    throw new IOException(e.getMessage());
                }
            }
        }
    
        public IUploadInformDao getUploadInformDao() {
            return uploadInformDao;
        }
        @Resource
        public void setUploadInformDao(IUploadInformDao uploadInformDao) {
            this.uploadInformDao = uploadInformDao;
        }
    }


    总结:到这里一个完整示例的多文件上传,再把数据保存到数据库已经完成了,这个示例仅供参考,毕竟我们用的框架是不一样,还有项目的ssh框架还有一定的分装,但是实现思路都是一样的,在这里留个笔记。也希望能给同学们一点启发,谢谢。

    你可能感兴趣的:(javaweb)