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

为什么做这个东东

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

需求是什么

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

必须要干的事情:

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);

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

效果图:

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

新鲜出炉的jquery fileupload 插件的更多相关文章

  1. 11个新鲜出炉的jQuery图像滑块插件

    如今图像滑块已成为一种流行的Web设计元素,通过滑块,你可以在有限的页面空间中展示更多的内容,带给用户更佳的浏览体验.本文将为你带来一些非常实用的jQuery图像滑块插件. 1.  Basic Sli ...

  2. 新鲜出炉的30个精美的 jQuery & CSS3 效果【附演示和教程】

    新鲜出炉的30个精美的 jQuery & CSS3 效果[附演示和教程]   作为最流行的 JavaScript 开发框架,jQuery 在现在的 Web 开发项目中扮演着重要角色,它简化了 ...

  3. 20个新鲜出炉的网站模板【HTML & PSD】

    这里给大家分享20 个新鲜出炉的免费网站模板.这些设计元素将成为你下一个项目的重要素材,可以帮你节省很多的时间.与往常一样,我们经常漫游网络,寻找最好的资源, HTML.CSS 和 PSD 等等,记得 ...

  4. Onsen UI – 新鲜出炉的 PhoneGap 界面框架

    Onsen UI 是一个基于元素自定义的 HTML5 UI 框架,用于构建你的移动前端.这个一个基于 Web 组件的概念的框架,让构建应用程序变得更加轻松.Onsen UI 专门针对 PhoneGap ...

  5. 微信小程序开发视频教程新鲜出炉

    微信小程序开发公测了,可是对于新手来说,不同的框架不同的开发机制,如何快速适应呢?微信小程序开发视频教程新鲜出炉了,从零开始一步一步搭建微信小程序,每个章节都会涉及到不同的知识点,等教程学习完你不但掌 ...

  6. 刚写完的商城erp + 这个商城前台,新鲜出炉。自己1个人写, 包括php框架和前端html页面.

    刚写完的商城erp + 这个商城前台,新鲜出炉.自己1个人写, 包括php框架和前端html页面. 刚写完的商城erp + 这个商城前台,新鲜出炉.自己1个人写, 包括php框架和前端html页面.

  7. 23套新鲜出炉的网站和手机界面 PSD 素材

    Web 用户界面,移动用户界面和线框套件对设计师很有用,因为这些套件让他们使用快速和有效的方式复制用户界面.这些类型的工具包提供了一个基本的用户界面元素,用于它们需要制作的网站或软件模型. 在这篇文章 ...

  8. 22套新鲜出炉的 Web & Mobile PSD 用户界面素材

    在这篇文章中,我们展示的是自由和清新的 UI 设计素材套件.这些线框图和 UI 设计工具包让设计师在设计用户界面原型的时候能够非常便利. Web 用户界面,移动用户界面和线框套件对设计师很有用,因为这 ...

  9. 分享25个新鲜出炉的 Photoshop 高级教程

    网络上众多优秀的 Photoshop 实例教程是提高 Photoshop 技能的最佳学习途径.今天,我向大家分享25个新鲜出炉的 Photoshop 高级教程,提高你的设计技巧,制作时尚的图片效果.这 ...

随机推荐

  1. iOS ipa包瘦身,iOS8及以下text段超60MB

    前沿 很早之前写过一篇相关文章,不过博客主机上跑路了之后数据没了,凭着记忆补了下相关资料 ipa安装包瘦身 清理无用图片,图片压缩(PNG换WebP和JPG),处于某种不可抗拒的原因,导致有部分3X图 ...

  2. Notyf - 超级简单、响应式的 JS 通知插件

    通知是网站的常用功能之一,可以用来显示消息.通告.提示等等.Notyf 是一款超级简单.响应式的 JS 通知插件,不依赖 jQuery 库,可以独立使用.赶紧试用一下吧! 在线演示      免费下载 ...

  3. 光盘作为yum源

    1.挂载光盘 mkdir /media/cdrom       //在/media下建立cdrom目录,默认情况是没有的  mount /dev/cdrom /mnt/cdrom2.进入 /etc/y ...

  4. 异步加载CSS

    说到加载 CSS 这种事儿不是很简单吗?像这样咯: <link rel="stylesheet" href="cssfile.css"> 这不就完事 ...

  5. libtorch初体验

    环境 Ubuntu -18.04.1, opencv3.4.0 ,  python 3.6,  cmake 3.5.0, pytorch 1.0. pytorch官网下载对应版本:https://py ...

  6. 使用WPF教你一步一步实现连连看(一)

    第一步: 问题,怎样动态的建立一个10*10的grid(布局) for (int i = 0; i < 10; i++) { RowDefinition rowDef = new RowDefi ...

  7. jquery 获得下拉框的值《转》

    获取Select : 获取select 选中的 text : $("#ddlRegType").find("option:selected").text(); ...

  8. Android实现两次点击返回键提示退出

    Android的很多app中,都有点击一次返回键提示再次点击退出app的功能. 今天就看了下实现的方式,其实就是在相应的Activity中重写了onKeyDown()方法.在onKeyDown()方法 ...

  9. WebLogic 8的安装与配置详谈

    本文主要是以windouw下32位的版本为例展开介绍,主要包括其安装与配置. 一.图形界面安装过程 1.双击安装程序server815_win32.exe,开始进行程序的安装. 2.点击Next按钮进 ...

  10. 三. Redis 主从复制

    特点 1. Master可以拥有多个Slave 2. 多个Slave除可以连接一个Master外,还可以连接多个Salve(避免Master挂掉不能同步,当Master挂掉,其中一个Slave会立即变 ...