zoukankan      html  css  js  c++  java
  • 新鲜出炉的jquery fileupload 插件

    内容属原创,转载请注明出处

    为什么做这个东东

    项目中需要用到一个多附件上传的控件,找了一圈没找到中意的(唯一一个中意点的还不开源,费用比较高),这不,只得自己抡刀上了。

    需求是什么

    这么个上传的东东,要做哪些事情呢?

    必须要干的事情:

    1. 不能太丑,可以很素。

        原生的input file实在和项目主体不太搭配,需要另外想办法。

    2. 需要支持上传多个附件,比如后台有个字段叫做 影像资料,这个影像资料,也许就是一张正面照,也许,还有一堆的证件照,需要支持多个。

    3. 需要一个页面上支持多个这样的控件,今天有个影像资料,明天可能就出来一个 资质证书,这不,就得俩了。

    4. 需要能查列表,上传、下载、删除

    最好有的内容:

    5. 实时进度条

    6. 图片类型的附件可以预览。

    7. 可以限制上传的附件类型。

    8. 支持配置上传单个或者多个

    上面这些东西,一个一个来呗。

    怎么开工

    做这么个东东,至少要涉及到两块内容:

    1. 前端展示

    2. 后端处理

    既然咱项目用了spring,用了jquery,那么,就从这两玩意入手呗,于是,决定这样干:

    1. 前端自定义一个jquery插件

    2. 后台基于springMVC和commons-fileupload-1.2.1.jar实现上传的具体业务

    闲话莫提,开始捉刀。

    前端插件的那些事

    jquery是个好东东,要搞个插件有非常具体的套路,直接往上面套就好了,关键在于,逻辑怎么实现?

    以前的项目用的是flash的插件,如今既然不想再依赖flash,那么,就用form提交来搞吧,步骤变成了这样子的:

    1. 初始化时调用后台query接口,生成列表,列表上支持下载和删除。

    2. 初始化时生成一个类型为 file的input,并绑定一个change事件 callback

    3. 在callback中,动态生成一个form和一个iframe,并且把原来的file移到新的form中,另外再生成一个file放到原来的位置。把该form扔到队列

    4. 如果当前没有提交的任务存在,那么生成一个提交的任务。

    提交的任务中又在干嘛呢?

    主要有下面几个事情要做:

    1. 当前有没有正在提交还没提交成功的form?如果有,继续下面的步骤,如果没有,从队列中拿一个未提交的form,提交,如果队列空了,任务结束。

    2. 当前提交的form的目的地(iframe)的内容有没有发生改变(通过检测某个具体的dom)?如果发生了改变,说明提交已经结束,进入结束的处理。如果没发生改变,那么,取进度条吧。

      2.1 提交已经结束,看下,成功还是失败?成功了,设置进度条,生成删除按钮,再从第一个步骤开始。失败了,提示下上传失败。

      2.2 提交还未结束,调用接口取下进度吧,同时,过个500毫秒从第一个步骤开始再来一次。

    嗯,前端所有的逻辑基本上都在这里了。

    后端的那些事

    既然用了commons-fileupload-1.2.1.jar,那么只要做如下事情:

    1. 新增类UploadProgressListener实现ProgressListener接口,在该接口的实现类中,首先从url里根据规则解析出来uploadId参数,然后往session例如该uploadId对应的进度。

        session里存的是个map,key为uploadId,value为进度值。
    2. 继承 CommonsMultipartResolver 实现一个类xx.xx.xx.CommonsMultipartResolver,在该实现类中通过类似下面代码注入进度条监听:

          String encoding = determineEncoding(request);
          FileUpload fileUpload = prepareFileUpload(encoding);
          ProgressListener pListener = new UploadProgressListener(request);
          fileUpload.setProgressListener(pListener);
    View Code

    3. 在spring的配置文件中配置multipartResolver为上面步骤中新实现的类: 

    <bean id="multipartResolver" class="xx.xx.xx.CommonsMultipartResolver" p:defaultEncoding="UTF-8" >

    嗯,差不多就这样了。只是,这里面有个比较大的坑

    在 UploadProgressListener 这个类中拿到的request的parameter一直是空的。。要等这个步骤做完之后request的参数才有值,这样,支持多个附件上传的那个参数uploadId怎么样都拿不到。。最后,幸好MVC支持在url里带参数,于是上传的url就变成了:

      @RequestMapping(value="/file/{uploadId}/upload.json")

    这样,可以通过规则在request中拿到getRequestURI()之后再解析出来uploadId的值

    差不多可以收工了。

    写在题外的

    用的时候,还要注意什么下面这么些东西:

    1. 后台存储附件需要这么张关系表,里面保存了 file_group_id,file_id,file_name,file_path,file_size 至少这么些数据。

    2. 控件基于jquery 1.7.2,未测试其他版本

    3. 配置控件 上传、新增、删除、下载以及获取进度条的action时,注意需要相对工程的根目录配置,前面不要带 /
    4. 控件的action需要返回json数据,需要注意如下内容:
      a. 新增返回的json为如下格式,至少需要返回fileId和fileGroupId字段:
      

    {model_list:[{"file_group_id":"XXXXX","file_id":"XXXXXXX"}]}

      同时,注意返回时,需要设置返回数据的头部信息为 HTML,java中为:

      

    response.setContentType("text/html;charset=UTF-8");

    b. 删除时后台通过参数 file_id 接收要删除的 文件编号,不抛异常则认为是删除成功

    c. 下载时后台通过参数 file_id 接收要下载的文件编号,返回文件流
    d. 获取文件列表时,后台通过url里的参数 fileGroupId查询该组号下的所有附件,的返回json数据为:

    {model_list:[{file_group_id:'XX',file_id:'XXX1',file_name:'XX文件',file_path:'test/test/XX文件_20140810010101.html',file_size:1001},{file_group_id:'XX',file_id:'XXX2',file_name:'XX文件',file_path:'test/test/XX文件_20140810010102.html',file_size:1001}]}

    e. 获取文件上传进度,返回的格式为json格式:

    {"percent":10}

    注意,为了支持多个文件上传读取进度,每一个文件上传时有一个唯一的 uploadId,获取文件上传进度需要根据该参数进行,提交时的参数名为 upload_id

    下载

    这个fileupload的前端插件的地址已经放在github上,路径:

    https://github.com/kevin82008/fileupload

    效果图:

    水平所限,如有不对,欢迎拍砖。

    ------------------------------------

    当天空没有颜色的时候,就用自己的双手画出绚烂的彩虹。程序员的天空,永远都是多彩多姿的。

  • 相关阅读:
    曹工说Spring Boot源码(18)-- Spring AOP源码分析三部曲,终于快讲完了 (aop:config完整解析【下】)
    曹工说Spring Boot源码(17)-- Spring从xml文件里到底得到了什么(aop:config完整解析【中】)
    曹工说Spring Boot源码(16)-- Spring从xml文件里到底得到了什么(aop:config完整解析【上】)
    曹工说Spring Boot源码(15)-- Spring从xml文件里到底得到了什么(context:load-time-weaver 完整解析)
    期货
    手机像素密度的计算公式
    线性代数第一讲 行列式01
    matlab找出某个元素的位置序号
    《树先生》影评
    当你的才华还不足以支撑起你的野心时,你就该静下心来学习
  • 原文地址:https://www.cnblogs.com/kevinYX/p/3903173.html
Copyright © 2011-2022 走看看