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组件实现文件上传时,需要创建一个工厂对象,并根据该工厂对象创建一个新的文件上传对象,具体代码如下:
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="data: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技术——带进度条的文件上传的更多相关文章
- Ajax实现带进度条的文件上传
Ajax实现带进度条的文件上传 文件上传页面运行效果 上传文件并显示进度条运行效果 代码如下; DiskFileItemFactory factory = new DiskFileItemFactor ...
- Android带进度条的文件上传,使用AsyncTask异步任务
最近项目中要做一个带进度条的上传文件的功能,学习了AsyncTask,使用起来比较方便,将几个方法实现就行,另外做了一个很简单的demo,希望能对大家有帮助,在程序中设好文件路径和服务器IP即可. A ...
- 采用formdata做跨域的、无刷新、带进度条的文件上传
以前做无刷新上传,都要用iframe,如果想有进度条,就千难万难,不得不用flash等插件来实现. 现在HTML5终于普及了,筒子们不用再那么痛苦了. 所有这一切都变得异常简单!! 不信?且看如下代码 ...
- 服务器文档下载zip格式 SQL Server SQL分页查询 C#过滤html标签 EF 延时加载与死锁 在JS方法中返回多个值的三种方法(转载) IEnumerable,ICollection,IList接口问题 不吹不擂,你想要的Python面试都在这里了【315+道题】 基于mvc三层架构和ajax技术实现最简单的文件上传 事件管理
服务器文档下载zip格式 刚好这次项目中遇到了这个东西,就来弄一下,挺简单的,但是前台调用的时候弄错了,浪费了大半天的时间,本人也是菜鸟一枚.开始吧.(MVC的) @using Rattan.Co ...
- 基于mvc三层架构和ajax技术实现最简单的文件上传
前台页面提交文件 <!DOCTYPE html> <html><head> <meta name="viewport" content=& ...
- HTML5利用FormData对象实现显示进度条的文件上传
摘自:https://blog.csdn.net/q1056843325/article/details/53759963 自己做是按这个实现的,兼容性还不错 完整简约的解决方案 下面的代码清单是包括 ...
- 带进度条的文件批量上传插件uploadify
有时项目中需要一个文件批量上传功能时,个人认为uploadify是快速简便的解决方案. 先上效果图: 一. 下载uploadify 从官网下载uploadify的Flash版本(Flash版本免费,另 ...
- 初识html5 File API实现带有进度提示的文件上传
Html5终于解决了上传文件的同时显示文件上传进度的老问题.现在大部分的网站用Flash去实现这一功能,还有一些网站继续采用Html <form>with enctype=multipar ...
- [SAP ABAP开发技术总结]文本文件、Excel文件上传下传
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
随机推荐
- 转: 让html5标签在ie8及以下的被正确解析的解决方案
最近仿的几个主题中,有几个是采用html5语法制作的,html5嘛,以后必然大势所趋,但是现有的很多浏览器并不支持这种新的标准. 而我制作网站习惯用的是chrome浏览器的,当然不存在不兼容问题了. ...
- STL front() ,back()和begin(),end()区别
首先看看vector里面的: reference front(); const_reference front() const; queue里面的: value_type& front(); ...
- Ubuntu实现双网卡双IP双待机
Ubuntu实现双网卡双IP双待机 待机是借用了手机中的说法,其实是电脑上有两个网卡,一个无线,一个有线的.要实现无线访问外网Google Baidu查资料,有线网卡直接连接开发板.在Ubuntu上配 ...
- CloudStack修复bug
CloudStack应用越来越广,但是随着测试也遇到了越来越多的bug. 不想等待新版本发布而且又急于修复某些bug的童鞋,可以参考下本文内容. CloudStack是java语言写成,发布时会发布为 ...
- MFC消息顺序
1.AfxWndProc() 该函数负责接收消息,找到消息所属的CWnd对象,然后调用AfxCallWndProc 2.AfxCallWndProc() 该函数负责保存消息(保存的内容主要 ...
- Python 連接 MySQL
Python 連接 MySQL MySQL 是十分流行的開源資料庫系統,很多網站也是使用 MySQL 作為後台資料儲存,而 Python 要連接 MySQL 可以使用 MySQL 模組.MySQLdb ...
- 详解Spring
Spring SSH框架中Struts2:是基于Web层,Hibernate:是基于持久化的,Spring:业务层,管理bean,它是一个容器,List,map, Set这里的内容,是适合已经学过了S ...
- SPI通信
SPI是由Motorola公司提出的一种同步串行外围接口:它在速度要求不高,低功耗,需要保存少量参数的智能化传感系统中得到了广泛应用: SPI是一个全双工的同步串行接口,在数据传输过程中,总线上只能是 ...
- ASP.net 学习路线(详细)
.net学习路线 入门篇1. 学习面向对象(OOP)的编程思想 许多高级语言都是面向对象的编程,.NET也不例外.如果您第一次接触面向对象的编程,就必须理解类.对象.字段.属性.方法和 ...
- POJ2728 最小比率生成树/0-1分数规划/二分/迭代(迭代不会)
用01分数规划 + prime + 二分 竟然2950MS惊险的过了QAQ 前提是在TLE了好几次下过的 = = 题目意思:有n个村庄,村庄在不同坐标和海拔,现在要对所有村庄供水,只要两个村庄之间有一 ...