基于Ajax技术实现文件上传带进度条
1.概述
在实际的Web应该开发或网站开发过程中,经常需要实现文件上传的功能。在文件上传过程中,经常需要用户进行长时间的等待,为了让用户及时了解上传进度,可以在上传文件的同时,显示文件的上传进度条。运行本实例,如图1所示,访问文件上传页面,单击“浏览”按钮选择要上传的文件,注意文件不能超过50MB,否则系统将给出错误提示。选择完要上传的文件后,单击“提交”按钮,将会上传文件并显示上传进度。
2.技术要点
主要是应用开源的Common-FileUpload组件来实现分段文件上传,从而实现在上传过程中,不断获取上传进度。下面对Common-FileUpload组件进行详细介绍。
Common-FileUpload组件时Apache组织下的jakarta-commons项目下的一个子项目,该组件可以方便地将multipart/form-data类型请求中的各种表单域解析出来。该组件需要另一个名为Common-IO的组件的支持。这两个组件包文件可以到http://commons.apache.org网站上进行下载。
(1)创建上传对象
在应该Common-FileUpload组件实现文件上传时,需要创建一个工厂对象,并根据该工厂对象创建一个新的文件上传对象,具体代码如下:
DiskFileItemFactoryfactory=newDiskFileItemFactory(); ServletFileUploadupload=newServletFileUpload(factory);
(2)解析上传请求
创建一个文件上传对象后,就可以应用该对象来解析上传请求,获取全部的表单项,可以通过文件上传对象的parseRequest()方法来实现。parseRequest()方法的语法结构如下:
publicListparseRequest(HttpServletRequestrequest)throwsFileUploadException
(3)FileItem类
在Common-FileUpload组件中,无论是文件域还是普通表单域,都当成FileItem对象来处理。如果该对象的isFormField()方法返回值为true,则表示是一个普通表单域,否则为一个文件域。在实现文件上传时,可以通过FileItem类的getName()方法获得上传文件的文件名,通过getSize()方法获得上传文件的大小。
3.具体实现
(1)创建request.js文件,在该文件中编写Ajax请求方法。
(2)新建文件上传页index.jsp,在该页中添加用于获得上传文件信息的表单以及表单元素,并添加用于显示进度条的<div>标签和显示百分比的<span>标签,关键代码如下:
<formenctype="multipart/form-data"method="post"action="UpLoad?action=uploadFile">
请选择上传的文件:<inputname="file"type="file"size="34">
注:文件大小请控制在50M以内。
<divid="progressBar"class="prog_border"align="left"> <imgsrc="images/progressBar.gif"width="0"height="13"id="imgProgress"></div> <spanid="progressPercent"style="width:40px;display:none">0%</span> <inputname="Submit"type="button"value="提交"onClick="deal(this.form)"> <inputname="Reset"type="reset"class="btn_grey"value="重置"></td> </form>
(3)新建上传文件的Servlet实现类UpLpad。在该类中编写实现文件上传的方法uploadFile(),在该方法中通过Common-FileUpload组件实现分段上传文件,并计算上传百分比,实时保存到Session中,关键代码如下:
publicvoiduploadFile(HttpServletRequestrequest,HttpServletResponseresponse) throwsServletException,IOException{ response.setContentType("text/html;charset=GBK"); request.setCharacterEncoding("GBK"); HttpSessionsession=request.getSession(); session.setAttribute("progressBar",0);//定义指定上传进度的Session变量 Stringerror=""; intmaxSize=50*1024*1024;//单个上传文件大小的上限 DiskFileItemFactoryfactory=newDiskFileItemFactory();//创建工厂对象 ServletFileUploadupload=newServletFileUpload(factory);//创建一个新的文件上传对象 try{ Listitems=upload.parseRequest(request);//解析上传请求 Iteratoritr=items.iterator();//枚举方法 while(itr.hasNext()){ FileItemitem=(FileItem)itr.next();//获取FileItem对象 if(!item.isFormField()){//判断是否为文件域 if(item.getName()!=null&&!item.getName().equals("")){//是否选择了文件 longupFileSize=item.getSize();//上传文件的大小 StringfileName=item.getName();//获取文件名 if(upFileSize>maxSize){ error="您上传的文件太大,请选择不超过50M的文件"; break; } //此时文件暂存在服务器的内存中 FiletempFile=newFile(fileName);//构造文件目录临时对象 StringuploadPath=this.getServletContext().getRealPath("/upload"); Filefile=newFile(uploadPath,tempFile.getName()); InputStreamis=item.getInputStream(); intbuffer=1024;//定义缓冲区的大小 intlength=0; byte[]b=newbyte[buffer]; doublepercent=0; FileOutputStreamfos=newFileOutputStream(file); while((length=is.read(b))!=-1){ percent+=length/(double)upFileSize*100D;//计算上传文件的百分比 fos.write(b,0,length);//向文件输出流写读取的数据 session.setAttribute("progressBar",Math.round(percent)); } fos.close(); Thread.sleep(1000);//线程休眠1秒 }else{ error="没有选择上传文件!"; } } } }catch(Exceptione){ e.printStackTrace(); error="上传文件出现错误:"+e.getMessage(); } if(!"".equals(error)){ request.setAttribute("error",error); request.getRequestDispatcher("error.jsp").forward(request,response); }else{ request.setAttribute("result","文件上传成功!"); request.getRequestDispatcher("upFile_deal.jsp").forward(request,response); } }
(4)在文件上传页index.jsp中,导入编写的Ajax请求方法的request.js文件,并编写获取上传进度的Ajax请求方法和Ajax回调函数,关键代码如下:
<scriptlanguage="javascript"src="js/request.js"></script> <scriptlanguage="javascript"> varrequest=false; functiongetProgress(){ varurl="showProgress.jsp";//服务器地址 varparam="nocache="+newDate().getTime();//每次请求URL参数都不同,避免上传时进度条不动 request=httpRequest("post",url,true,callbackFunc,param);//调用请求方法 } //Ajax回调函数 functioncallbackFunc(){ if(request.readyState==4){//判断响应是否完成 if(request.status==200){//判断响应是否成功 varh=request.responseText;//获得返回的响应数据,该数据位上传进度百分比 h=h.replace(/\s/g,"");//去除字符串中的Unicode空白符 document.getElementById("progressPercent").style.display="";//显示百分比 progressPercent.innerHTML=h+"%";//显示完成的百分比 document.getElementById("progressBar").style.display="block";//显示进度条 document.getElementById("imgProgress").width=h*(235/100);//显示完成的进度 } } } </script>
(5)编写showProgress.jsp页面,在该页中应用EL表达式输出保存在session域中的上传进度条的值,具体代码如下:
<%@pagecontentType="text/html"pageEncoding="GBK"%> ${progressBar}
(6)编写表单提交按钮onclick事件所调用的JavaScript方法,在该方法通过window对象的setInterval()方法每隔一定时间请求一次服务器,获得最新的上传进度,关键代码如下:
functiondeal(form){ form.submit();//提交表单 timer=window.setInterval("getProgress()",500);//每隔500毫秒获取一次上传进度 }
以上所述是小编给大家介绍的基于Ajax技术实现文件上传带进度条的相关知识,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!