欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

基于Ajax技术实现文件上传带进度条

程序员文章站 2023-02-21 20:24:49
1.概述 在实际的web应该开发或网站开发过程中,经常需要实现文件上传的功能。在文件上传过程中,经常需要用户进行长时间的等待,为了让用户及时了解上传进度,可以在上传文...

1.概述

在实际的web应该开发或网站开发过程中,经常需要实现文件上传的功能。在文件上传过程中,经常需要用户进行长时间的等待,为了让用户及时了解上传进度,可以在上传文件的同时,显示文件的上传进度条。运行本实例,如图1所示,访问文件上传页面,单击“浏览”按钮选择要上传的文件,注意文件不能超过50mb,否则系统将给出错误提示。选择完要上传的文件后,单击“提交”按钮,将会上传文件并显示上传进度。

2.技术要点

主要是应用开源的common-fileupload组件来实现分段文件上传,从而实现在上传过程中,不断获取上传进度。下面对common-fileupload组件进行详细介绍。

common-fileupload组件时apache组织下的jakarta-commons项目下的一个子项目,该组件可以方便地将multipart/form-data类型请求中的各种表单域解析出来。该组件需要另一个名为common-io的组件的支持。这两个组件包文件可以到网站上进行下载。

(1)创建上传对象

在应该common-fileupload组件实现文件上传时,需要创建一个工厂对象,并根据该工厂对象创建一个新的文件上传对象,具体代码如下:

diskfileitemfactory factory = new diskfileitemfactory();
servletfileupload upload = new servletfileupload(factory); 

(2)解析上传请求

创建一个文件上传对象后,就可以应用该对象来解析上传请求,获取全部的表单项,可以通过文件上传对象的parserequest()方法来实现。parserequest()方法的语法结构如下:

public list parserequest(httpservletrequest request) throws fileuploadexception 

(3)fileitem类

在common-fileupload组件中,无论是文件域还是普通表单域,都当成fileitem对象来处理。如果该对象的isformfield()方法返回值为true,则表示是一个普通表单域,否则为一个文件域。在实现文件上传时,可以通过fileitem类的getname()方法获得上传文件的文件名,通过getsize()方法获得上传文件的大小。

3.具体实现

(1)创建request.js文件,在该文件中编写ajax请求方法。

(2)新建文件上传页index.jsp,在该页中添加用于获得上传文件信息的表单以及表单元素,并添加用于显示进度条的<div>标签和显示百分比的<span>标签,关键代码如下:

<form enctype="multipart/form-data" method="post" action="upload?action=uploadfile">

请选择上传的文件:<input name="file" type="file" size="34">

注:文件大小请控制在50m以内。

<div id="progressbar" class="prog_border" align="left">
<img src="images/progressbar.gif" width="0" height="13" id="imgprogress"></div>
<span id="progresspercent" style="width:40px;display:none">0%</span>
<input name="submit" type="button" value="提交" onclick="deal(this.form)">
<input name="reset" type="reset" class="btn_grey" value="重置"></td>
</form> 

(3)新建上传文件的servlet实现类uplpad。在该类中编写实现文件上传的方法uploadfile(),在该方法中通过common-fileupload组件实现分段上传文件,并计算上传百分比,实时保存到session中,关键代码如下:

public void uploadfile(httpservletrequest request, httpservletresponse response)
throws servletexception, ioexception {
response.setcontenttype("text/html;charset=gbk");
request.setcharacterencoding("gbk");
httpsession session=request.getsession();
session.setattribute("progressbar",0); //定义指定上传进度的session变量
string error = "";
int maxsize=50*1024*1024; //单个上传文件大小的上限
diskfileitemfactory factory = new diskfileitemfactory(); //创建工厂对象
servletfileupload upload = new servletfileupload(factory); //创建一个新的文件上传对象
try {
list items = upload.parserequest(request); // 解析上传请求
iterator itr = items.iterator(); // 枚举方法
while (itr.hasnext()) {
fileitem item = (fileitem) itr.next(); //获取fileitem对象
if (!item.isformfield()) { // 判断是否为文件域
if (item.getname() != null && !item.getname().equals("")) {//是否选择了文件
long upfilesize=item.getsize(); //上传文件的大小
string filename=item.getname(); //获取文件名
if(upfilesize>maxsize){
error="您上传的文件太大,请选择不超过50m的文件";
break;
}
// 此时文件暂存在服务器的内存中
file tempfile = new file(filename); //构造文件目录临时对象
string uploadpath = this.getservletcontext().getrealpath("/upload");
file file = new file(uploadpath,tempfile.getname()); 
inputstream is=item.getinputstream();
int buffer=1024; //定义缓冲区的大小
int length=0;
byte[] b=new byte[buffer];
double percent=0;
fileoutputstream fos=new fileoutputstream(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 (exception e) {
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回调函数,关键代码如下:

<script language="javascript" src="js/request.js"></script>
<script language="javascript">
var request = false;
function getprogress(){ 
var url="showprogress.jsp"; //服务器地址
var param ="nocache="+new date().gettime(); //每次请求url参数都不同 ,避免上传时进度条不动
request=httprequest("post",url,true,callbackfunc,param); //调用请求方法 
}
//ajax回调函数
function callbackfunc(){
if( request.readystate==4 ){ //判断响应是否完成 
if( request.status == 200 ){ //判断响应是否成功
var h = 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域中的上传进度条的值,具体代码如下:

<%@page contenttype="text/html" pageencoding="gbk"%>
${progressbar} 

(6)编写表单提交按钮onclick事件所调用的javascript方法,在该方法通过window对象的setinterval()方法每隔一定时间请求一次服务器,获得最新的上传进度,关键代码如下:

function deal(form){
form.submit(); //提交表单
timer=window.setinterval("getprogress()",500); //每隔500毫秒获取一次上传进度
}

以上所述是小编给大家介绍的基于ajax技术实现文件上传带进度条的相关知识,希望对大家有所帮助