springMVC上传文件 带有进度条
来源:互联网 发布:三维软件开发平台 编辑:程序博客网 时间:2024/05/16 23:48
springMVC上传文件 带有进度条
一、需求
一个文件上传的功能(带进度条)
二、实现方式
文件上传应该大部分人都接触过,一般都是基于commons-fileupload组件来实现,SpringMVC的文件上传功能也是在commons-fileupload组件提供的功能上面做了一些包装功能,使文件上传开发更容易方便。
参考:http://my.oschina.net/xiaotian120/blog/198225
三、遇到的问题
采用以上方式,会有比较大的问题。
在监听器那边采用的存到session中,那么
如果是同一个浏览器同一个标签页有同时触发了两次上传的操作,那么进度条的数值会乱串!
如果是同一个浏览器不同标签页同时上传,同样进度条的数值也会乱串!!!
四、改进方式
总的来说,在提交的时候,对上传任务进行编号,js端以时间戳加随机数编号就可以,把编号值传入服务端。在服务端session中对上传进度和编号进行一对一放入。获取的时候对比编号找出自己的那个上传任务,然后展示进度条就ok了。
详细点简单点的说就是将一次请求上传文件看做是一个线程,那么一次上传文件的线程id是唯一的,通过维护一个静态的ConcurrentHashMap值,就可以在监听器那边获取到客户端这边传入的文件编号。
五、附录代码
1.进度条代码(比较简单的,采用两个div,其中一个div作为背景,另一个div作为进度展示的宽度)
<html> <head> <title>进度条</title> <style type="text/css"> .container{ width:450px; border:1px solid #6C9C2C; height:25px; }#bar{ background:#95CA0D; float:left; height:100%; text-align:center; line-height:150%; } </style> <script type="text/javascript"> function run(){ var bar = document.getElementById("bar"); var total = document.getElementById("total"); bar.style.width=parseInt(bar.style.width) + 1 + "%"; //total.innerHTML = bar.style.width; document.getElementById("bar1").innerHTML = bar.style.width; if(bar.style.width == "100%"){ window.clearTimeout(timeout); return; } var timeout=window.setTimeout("run()",100); } window.onload = function(){ run(); } </script> </head> <body> <div class="container"> <div id="bar1" style=" position: fixed;width:450px;text-align:center"></div> <div id="bar" style="width:0%;"></div> </div> <span id="total"></span> </body> </html>2.js 计算上传文件的大小
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="DEscription" contect="my code demo" /> <meta name="Author" contect="Michael@www.micmiu.com" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>js验证文件大小</title> </head> <body> <img id="tempimg" dynsrc="" src="" style="display:none" /> <input type="file" name="file" id="fileuploade" size="40" /> <input type="button" name ="check" value="checkfilesize" onclick="checkfile()"/> </body> <script type="text/javascript"> var maxsize = 2*1024*1024;//2M var errMsg = "上传的附件文件不能超过2M!!!"; var tipMsg = "您的浏览器暂不支持计算上传文件的大小,确保上传文件不要超过2M,建议使用IE、FireFox、Chrome浏览器。"; function checkfile(){ try{ var obj_file = document.getElementById("fileuploade"); if(obj_file.value==""){ alert("请先选择上传文件"); return; } var filesize = 0; //1.非IEif(obj_file.files != null && typeof(obj_file.files)!="undefined"){filesize = obj_file.files[0].size; alert("非IE内核:"+filesize);}else{//2.IE var obj_img = document.getElementById('tempimg'); obj_img.dynsrc=obj_file.value; filesize = obj_img.fileSize; alert("IE内核:"+filesize);}if(typeof(filesize) != 'number'){alert(tipMsg); return; } alert("类型typeof:"+typeof(filesize)); if(filesize==-1){ alert(tipMsg); return; }else if(filesize>maxsize){ alert(errMsg); return; }else{ alert("文件大小符合要求"); return; } }catch(e){ alert(e); } } </script> </html>
3.服务端改进的监听器代码:
01.新建GlobalThreadMap类,该类主要维护文件上传 的文件标识 (主要通过线程id)注意,在上传文件完成之后需要在上传文件的action中需要执行两个remove方法。
public class GlobalThreadMap {//维护文件标识idpublic final static ConcurrentHashMap<Long, String> uploadKeys = new ConcurrentHashMap<Long, String>();//维护session 中进度条数值public static ConcurrentHashMap<String, Progress> resMap = new ConcurrentHashMap<String, Progress>();public static void putKey(String uploadKey) {long id = Thread.currentThread().getId();uploadKeys.put(id, uploadKey);System.out.println("GlobalThreadMap putKey:" + id + " " + uploadKey);System.out.println("当前GlobalThreadMap uploadKeys的值是: "+uploadKeys);}public static String getKey() {returnuploadKeys.get(Thread.currentThread().getId());}public static void removeKey() {uploadKeys.remove(Thread.currentThread().getId());}public static void putResValue(Progress progress) {resMap.put(getKey(), progress);}public static Progress getResValueByKey() {returnresMap.get(getKey());}public static void removeResKey() {resMap.remove(getKey());}}
02.在扩展的监听器的类CustomMultipartResolver中方法resolveMultipart中:
public MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException { // 获取到request,要用到session this.request = request; //设置值 String random = request.getParameter("random"); GlobalThreadMap.putKey(random); return super.resolveMultipart(request); }03.在具体监听器实现这边FileUploadProgressListener
public class FileUploadProgressListener implements ProgressListener {private HttpSession session;public FileUploadProgressListener() {}public FileUploadProgressListener(HttpSession session) {this.session = session;Progress status = new Progress();// 设置值GlobalThreadMap.putResValue(status);session.setAttribute("upload_ps", GlobalThreadMap.resMap);// 这是现在的// 但是key去取出来是一个空的值,我是在上传文件开始的地方设置的值// session.setAttribute("upload_ps", status); //这是之前的将进度条的数值设置到session里面}/** * pBytesRead 到目前为止读取文件的比特数 pContentLength 文件总大小 pItems 目前正在读取第几个文件 */public void update(long pBytesRead, long pContentLength, int pItems) {String key = GlobalThreadMap.getKey();Map<String, Progress> map = (Map<String, Progress>) session.getAttribute("upload_ps");Progress status = map.get(key);status.setBytesRead(pBytesRead);status.setContentLength(pContentLength);status.setItems(pItems);status.setPercent(status.getPercent());status.setSpeed(status.getSpeed());status.setMbRead(status.getMbRead());// 设置值GlobalThreadMap.putResValue(status);session.setAttribute("upload_ps", GlobalThreadMap.resMap);}}
04.同样的,在实时获取进度条数值的这边的action中,也需要稍稍修改一点:
@RequestMapping(value = "/upfile/progress.do", method = RequestMethod.POST )@ResponseBodypublic String initCreateInfo(HttpServletRequest request) {String random = request.getParameter("random"); Map<String, Progress> map = (Map<String, Progress>) request.getSession().getAttribute("upload_ps");if(map == null ){return "{}";}Progress status = map.get(random);JSONObject jsonStu = JSONObject.fromObject(status);return jsonStu.toString();}05.对了,xml配置那边,需要将上传文件的的监听器配置成多例的
<bean id="multipartResolver" scope="prototype"class="com.sunsharing.ihome.air.web.common.fileupload.CustomMultipartResolver"> <property name="defaultEncoding" value="UTF-8" /> <property name="maxUploadSize" value="1000000000000" /></bean>
ok。改造完成。
====================================
====================================
====================================
1 0
- springMVC上传文件 带有进度条
- plupload +springMVC实例应用(IE9下,文件多选,上传,终止,带有进度条)
- bootstrap文件上传的使用,带有进度条
- SpringMVC实现文件上传进度条
- Springmvc文件上传,带进度条
- springmvc + h5(进度条)文件上传
- 基于SpringMVC文件上传服务器端进度条实现
- 基于SpringMVC文件上传服务器端进度条实现
- springMVC+ajax 文件上传 带进度条
- Extjs+SpringMvc 上传文件加进度条
- SpringMVC之文件上传(进度条显示)
- 基于SpringMVC文件上传服务器端进度条实现
- springMVC+ajax 文件上传 带进度条
- commons-fileupload和dwr实现带有进度条的文件上传
- RxJava+Retrofit+MVP 带有进度条的文件上传
- 带有进度条文件上传(UploadFile+AJAX+监听器)
- Uploadify上传,可以上传多个文件,带有进度条,希望有所帮助!
- 使用Html5异步上传文件,支持跨域,带有上传进度条
- 讯飞语音开发之文本理解
- 趣味小算法之递归
- oracle 安装步骤 登录 导入表 详细步骤
- Qt程序分析_broadcastUDP
- linux apr安装
- springMVC上传文件 带有进度条
- NOIP2008题解
- photoview-library 图片的缩放
- LVS原理介绍及安装过程
- iOS之NSJSONReadingOptions的三个选项
- java lambda学习
- 虚幻4 内存优化工具
- HierarchyViewer如何获取app UI结构
- C# 拖拽下载实现