
麦子学院 2016-07-02 01:03
如何在网页中实现带进度条的文件上传
回复:0 查看:3795
在
ajax入门http://www.maiziedu.com/course/351/知识学习中,通过
ajax
技术实现带进度条的文件上传是必须的知识点之一,本文就将和大家分享这部分内容,一起来看看吧。
1.
概述
在实际的
Web
应该开发或网站开发过程中,经常需要实现文件上传的功能。在文件上传过程中,经常需要用户进行长时间的等待,为了让用户及时了解上传进度,可以在上传文件的同时,显示文件的上传进度条。本实例将利用
Ajax来实现
:
访问文件上传页面,单击“浏览”按钮选择要上传的文件,注意文件不能超过
50MB
,否则系统将给出错误提示。选择完要上传的文件后,单击“提交”按钮,将会上传文件并显示上传进度。
2.
技术要点
主要是应用开源的
Common-FileUpload
组件来实现分段文件上传,从而实现在上传过程中,不断获取上传进度。下面对
Common-FileUpload
组件进行详细介绍。
Common-FileUpload
组件时
Apache
组织下的
jakarta-commons
项目下的一个子项目,该组件可以方便地将
multipart/form-data
类型请求中的各种表单域解析出来。该组件需要另一个名为
Common-IO
的组件的支持。这两个组件包文件可以到
http://commons.apache.org
网站上进行下载。
(
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
,在该页中添加用于获得上传文件信息的表单以及表单元素,并添加用于显示进度条的
标签和显示百分比的
标签,关键代码如下:
请选择上传的文件:
注:文件大小请控制在
50M
以内。

0%
(
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
回调函数,关键代码如下:
(
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
毫秒获取一次上传进度
}
原文来自:
柯南&
的博客