新鲜出炉的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);
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 插件的更多相关文章
- 11个新鲜出炉的jQuery图像滑块插件
如今图像滑块已成为一种流行的Web设计元素,通过滑块,你可以在有限的页面空间中展示更多的内容,带给用户更佳的浏览体验.本文将为你带来一些非常实用的jQuery图像滑块插件. 1. Basic Sli ...
- 新鲜出炉的30个精美的 jQuery & CSS3 效果【附演示和教程】
新鲜出炉的30个精美的 jQuery & CSS3 效果[附演示和教程] 作为最流行的 JavaScript 开发框架,jQuery 在现在的 Web 开发项目中扮演着重要角色,它简化了 ...
- 20个新鲜出炉的网站模板【HTML & PSD】
这里给大家分享20 个新鲜出炉的免费网站模板.这些设计元素将成为你下一个项目的重要素材,可以帮你节省很多的时间.与往常一样,我们经常漫游网络,寻找最好的资源, HTML.CSS 和 PSD 等等,记得 ...
- Onsen UI – 新鲜出炉的 PhoneGap 界面框架
Onsen UI 是一个基于元素自定义的 HTML5 UI 框架,用于构建你的移动前端.这个一个基于 Web 组件的概念的框架,让构建应用程序变得更加轻松.Onsen UI 专门针对 PhoneGap ...
- 微信小程序开发视频教程新鲜出炉
微信小程序开发公测了,可是对于新手来说,不同的框架不同的开发机制,如何快速适应呢?微信小程序开发视频教程新鲜出炉了,从零开始一步一步搭建微信小程序,每个章节都会涉及到不同的知识点,等教程学习完你不但掌 ...
- 刚写完的商城erp + 这个商城前台,新鲜出炉。自己1个人写, 包括php框架和前端html页面.
刚写完的商城erp + 这个商城前台,新鲜出炉.自己1个人写, 包括php框架和前端html页面. 刚写完的商城erp + 这个商城前台,新鲜出炉.自己1个人写, 包括php框架和前端html页面.
- 23套新鲜出炉的网站和手机界面 PSD 素材
Web 用户界面,移动用户界面和线框套件对设计师很有用,因为这些套件让他们使用快速和有效的方式复制用户界面.这些类型的工具包提供了一个基本的用户界面元素,用于它们需要制作的网站或软件模型. 在这篇文章 ...
- 22套新鲜出炉的 Web & Mobile PSD 用户界面素材
在这篇文章中,我们展示的是自由和清新的 UI 设计素材套件.这些线框图和 UI 设计工具包让设计师在设计用户界面原型的时候能够非常便利. Web 用户界面,移动用户界面和线框套件对设计师很有用,因为这 ...
- 分享25个新鲜出炉的 Photoshop 高级教程
网络上众多优秀的 Photoshop 实例教程是提高 Photoshop 技能的最佳学习途径.今天,我向大家分享25个新鲜出炉的 Photoshop 高级教程,提高你的设计技巧,制作时尚的图片效果.这 ...
随机推荐
- Go语言学习笔记(一) [Go语言的HelloWorld]
日期:2014年7月18日 1.简介 Go 编程语言是一个使得程序员更加有效率的开源项目.Go 是有表达力.简 洁.清晰和有效率的.它的并行机制使其很容易编写多核和网络应用,而新奇的类型系 ...
- oracle 外连接以及用on和where 的区别
Oracle 外连接(OUTER JOIN)包括以下: 左外连接(左边的表不加限制) 右外连接(右边的表不加限制) 全外连接(左右两表都不加限制) 对应SQL:LEFT/RIGHT/FULL OUT ...
- C# 基础运算符及运算
本节主要讲述运算符的分类及其实际运用 运算符 分类 符号 解释 优先级 算数 ++ -- 加加(加1) 减减(减1) 由高到低,即执行顺序由上到下(圆括号的优先级最高) * / % 乘 除 ...
- Java的第6天,学习运算符
提到运算符我们就会想起 加 减 乘 除: Java中的一些运算符:关系运算符.逻辑运算符.赋值运算符.和条件运算符: 其中算术运算符有:+ , - , * , \, % ,++, -- ; + , - ...
- 【Java基础】1、java中的instanceof
instanceof是Java.php的一个二元操作符(运算符),和==,>,<是同一类东西.由于它是由字母组成的,所以也是Java的保留关键字.它的作用是判断其左边对象是否为其右边类的实 ...
- Java基础回顾Application(二)
application对象 1 什么是application对象 ? (1) 当Web服务器启动时,Web服务器会自动创建一个application对象.application对象一旦创建,它将一直存 ...
- 微信服务号获取openid方法
public function tetst(){ if(!isset($_GET['code'])){ $APPID = $this->app_id; $ran = rand(1,100); / ...
- Window7 上跑 Spark 单机模式
一.下载Spark 下载地址:http://www.eu.apache.org/dist/spark/spark-1.5.2/spark-1.5.2-bin-hadoop2.4.tgz 我这里测试这个 ...
- nativefier(一行代码将任意网页转化为桌面应用)
刚刚在看前端九部的手册的时候,发现一个之前没有用过的骚东西,看上去还挺好用,我这个好奇心瞬间就窜的老高了,赶紧试一试,看看这个东西有没有必要收入我的胯下 结果实验完了之后, 必须必须要强行安利给你们 ...
- 【代码笔记】Web-ionic-卡片
一,效果图. 二,代码. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...