AJAX JSP实现基于WEB的文件上传的进度控制.docx
《AJAX JSP实现基于WEB的文件上传的进度控制.docx》由会员分享,可在线阅读,更多相关《AJAX JSP实现基于WEB的文件上传的进度控制.docx(22页珍藏版)》请在冰豆网上搜索。
AJAXJSP实现基于WEB的文件上传的进度控制
1.引言
2.实现代码
2.1.服务器端代码
文件上传状态类(FileUploadStatus)
文件上传状态侦听类(FileUploadListener)
后台服务类(BackGroundService)
文件上传状态控制类(BeanControler)
2.2.客户端代码
AjaxWrapper.js
fileUpload.html
result.jsp
fileUpload.css
2.3.配置文件
3.结语
1. 引言
基于浏览器的文件上传,特别是对于通过标签来实现上传的情况,存在着严重的性能问题,因为用户提交了文件之后,在浏览器把文件上传到服务器的过程中,界面看上去似乎是静止的,如果是小文件还好些,如果不幸需要上传的是几兆、几十兆甚至上百兆的文件,我相信那是一种非常痛苦的体验,我们中间的很多人应该都有过此种不堪的经历。
(一笑)
现在我就针对这个问题给出一个解决方案,我们将实现一个具有监控能力的WEB上传的程序——它不仅把文件上传到服务器,而且"实时地"监视文件上传的实际过程。
解决方案的基本思路是这样的:
∙ 在Form提交上传文件同时,使用AJAX周期性地从Servlet轮询上传状态信息
∙ 然后,根据此信息更新进度条和相关文字,及时反映文件传输状态
∙ 如果用户取消上传操作,则进行相应的现场清理工作:
删除已经上传的文件,在Form提交页面中显示相关信息
∙ 如果上传完毕,显示已经上传的文件内容(或链接)
在介绍源代码之前,我们先来看看程序运行界面:
2. 实现代码
实现代码想当然的有服务器端代码和客户端代码(呵呵),我们先从服务器端开始。
2.1. 服务器端代码
文件上传状态类(FileUploadStatus)
使用FileUploadStatus这个类记录文件上传状态,并将其作为服务器端与web客户端之间通信的媒介,通过对这个类对象提供上传状态作为服务器回应发送给web客户端,web客户端使用JavaScript获得文件上传状态。
源代码如下:
/**
*本例程演示了通过Web上传文件过程中的进度显示。
您可以对本例程进行任何修改和使用。
*如果需要转载本例程,请您注明作者。
*
*作者:
刘作晨
*EMail:
*/
package;
importjava.util.*;
publicclassFileUploadStatus{
//上传用户地址
privateStringuploadAddr;
//上传总量
privatelonguploadTotalSize=0;
//读取上传总量
privatelongreadTotalSize=0;
//当前上传文件号
privateintcurrentUploadFileNum=0;
//成功读取上传文件数
privateintsuccessUploadFileCount=0;
//状态
privateStringstatus="";
//处理起始时间
privatelongprocessStartTime=0l;
//处理终止时间
privatelongprocessEndTime=0l;
//处理执行时间
privatelongprocessRunningTime=0l;
//上传文件URL列表
privateListuploadFileUrlList=newArrayList();
//取消上传
privatebooleancancel=false;
//上传base目录
privateStringbaseDir="";
publicFileUploadStatus(){
}
publicStringgetBaseDir(){
returnbaseDir;
}
publicvoidsetBaseDir(StringbaseDir){
this.baseDir=baseDir;
}
publicbooleangetCancel(){
returncancel;
}
publicvoidsetCancel(booleancancel){
this.cancel=cancel;
}
publicListgetUploadFileUrlList(){
returnuploadFileUrlList;
}
publicvoidsetUploadFileUrlList(ListuploadFileUrlList){
this.uploadFileUrlList=uploadFileUrlList;
}
publiclonggetProcessRunningTime(){
returnprocessRunningTime;
}
publicvoidsetProcessRunningTime(longprocessRunningTime){
this.processRunningTime=processRunningTime;
}
publiclonggetProcessEndTime(){
returnprocessEndTime;
}
publicvoidsetProcessEndTime(longprocessEndTime){
this.processEndTime=processEndTime;
}
publiclonggetProcessStartTime(){
returnprocessStartTime;
}
publicvoidsetProcessStartTime(longprocessStartTime){
this.processStartTime=processStartTime;
}
publiclonggetReadTotalSize(){
returnreadTotalSize;
}
publicvoidsetReadTotalSize(longreadTotalSize){
this.readTotalSize=readTotalSize;
}
publicintgetSuccessUploadFileCount(){
returnsuccessUploadFileCount;
}
publicvoidsetSuccessUploadFileCount(intsuccessUploadFileCount){
this.successUploadFileCount=successUploadFileCount;
}
publicintgetCurrentUploadFileNum(){
returncurrentUploadFileNum;
}
publicvoidsetCurrentUploadFileNum(intcurrentUploadFileNum){
this.currentUploadFileNum=currentUploadFileNum;
}
publicStringgetStatus(){
returnstatus;
}
publicvoidsetStatus(Stringstatus){
this.status=status;
}
publiclonggetUploadTotalSize(){
returnuploadTotalSize;
}
publicStringgetUploadAddr(){
returnuploadAddr;
}
publicvoidsetUploadTotalSize(longuploadTotalSize){
this.uploadTotalSize=uploadTotalSize;
}
publicvoidsetUploadAddr(StringuploadAddr){
this.uploadAddr=uploadAddr;
}
publicStringtoJSon(){
StringBufferstrJSon=newStringBuffer();
strJSon.append("{UploadTotalSize:
").append(getUploadTotalSize()).append(
",")
.append("ReadTotalSize:
").append(getReadTotalSize()).append(",")
.append("CurrentUploadFileNum:
").append(getCurrentUploadFileNum()).
append(",")
.append("SuccessUploadFileCount:
").append(
getSuccessUploadFileCount()).append(",")
.append("Status:
'").append(getStatus()).append("',")
.append("ProcessStartTime:
").append(getProcessStartTime()).
append(",")
.append("ProcessEndTime:
").append(getProcessEndTime()).append(
",")
.append("ProcessRunningTime:
").append(getProcessRunningTime()).
append(",")
.append("Cancel:
").append(getCancel()).append("}");
returnstrJSon.toString();
}
}
文件上传状态侦听类(FileUploadListener)
使用Common-FileUpload1.2版本()。
此版本提供了能够监视文件上传情况的ProcessListener接口,使开发者通过FileUploadBase类对象的setProcessListener方法植入自己的Listener。
FileUploadListener类实现了ProcessListener,在整个文件上传过程中,它对上传进度进行监控,并且根据上传情况实时的更新上传状态Bean。
源代码如下:
/**
*本例程演示了通过Web上传文件过程中的进度显示。
您可以对本例程进行任何修改和使用。
*如果需要转载本例程,请您注明作者。
*
*作者:
刘作晨
*EMail:
*/
package;
import;
import;
publicclassFileUploadListenerimplementsProgressListener{
privateHttpServletRequestrequest=null;
publicFileUploadListener(HttpServletRequestrequest){
this.request=request;
}
/**
*更新状态
*/
publicvoidupdate(longpBytesRead,longpContentLength,intpItems){
FileUploadStatusstatusBean=BackGroundService.getStatusBean(request);
statusBean.setUploadTotalSize(pContentLength);
//读取完成
if(pContentLength==-1){
statusBean.setStatus("完成对"+pItems+"个文件的读取:
读取了"+pBytesRead+"bytes.");
statusBean.setReadTotalSize(pBytesRead);
statusBean.setSuccessUploadFileCount(pItems);
statusBean.setProcessEndTime(System.currentTimeMillis());
statusBean.setProcessRunningTime(statusBean.getProcessEndTime());
//读取中
}else{
statusBean.setStatus("当前正在处理第"+pItems+"个文件:
已经读取了"+pBytesRead+
"/"+pContentLength+"bytes.");
statusBean.setReadTotalSize(pBytesRead);
statusBean.setCurrentUploadFileNum(pItems);
statusBean.setProcessRunningTime(System.currentTimeMillis());
}
BackGroundService.saveStatusBean(request,statusBean);
}
}
后台服务类(BackGroundService)
BackGroundService这个Servlet类负责接收FormPost数据、回应状态轮询请求、处理取消文件上传的请求。
尽管可以把这些功能相互分离开来,但为了简单明了,还是将它们放到Servlet中,只是由不同的方法进行分割。
源代码如下:
/**
*本例程演示了通过Web上传文件过程中的进度显示。
您可以对本例程进行任何修改和使用。
*如果需要转载本例程,请您注明作者。
*
*作者:
刘作晨
*EMail:
*/
package;
/**
*Title:
后台服务
**Description:
为客户端提供上传及文件传输状态查询服务
*
*/
import;
import;
import;
import;
import;
import;
import;
import;
import;
import;
publicclassBackGroundServiceextendsimplements
{
publicstaticfinalStringUPLOAD_DIR="/upload";
publicstaticfinalStringDEFAULT_UPLOAD_FAILURE_URL="./result.jsp";
publicBackGroundService(){
super();
}
protectedvoiddoGet(HttpServletRequestrequest,
HttpServletResponseresponse)throwsServletException,
IOException{
doPost(request,response);
}
/**
*从文件路径中取出文件名
*/
privateStringtakeOutFileName(StringfilePath){
intpos=filePath.lastIndexOf(File.separator);
if(pos>0){
returnfilePath.substring(pos+1);
}else{
returnfilePath;
}
}
/**
*从request中取出FileUploadStatusBean
*/
publicstaticFileUploadStatusgetStatusBean(
HttpServletRequestrequest){
BeanControlerbeanCtrl=BeanControler.getInstance();
returnbeanCtrl.getUploadStatus(request.getRemoteAddr());
}
/**
*把FileUploadStatusBean保存到类控制器BeanControler
*/
publicstaticvoidsaveStatusBean(
HttpServletRequestrequest,
FileUploadStatusstatusBean){
statusBean.setUploadAddr(request.getRemoteAddr());
BeanControlerbeanCtrl=BeanControler.getInstance();
beanCtrl.setUploadStatus(statusBean);
}
/**
*删除已经上传的文件
*/
privatevoiddeleteUploadedFile(HttpServletRequestrequest){
FileUploadStatussatusBean=getStatusBean(request);
for(inti=0;iFileuploadedFile=newFile(request.getRealPath(UPLOAD_DIR)+
File.separator+
satusBean.getUploadFileUrlList().
get(i));
uploadedFile.delete();
}
satusBean.getUploadFileUrlList().clear();
satusBean.setStatus("删除已上传的文件");
saveStatusBean(request,satusBean);
}
/**
*上传过程中出错处理
*/
privatevoiduploadExceptionHandle(
HttpServletRequestrequest,
StringerrMsg)throwsServletException,IOException{
//首先删除已经上传的文件
deleteUploadedFile(request);
FileUploadStatussatusBean=getStatusBean(request);
satusBean.setStatus(errMsg);
saveStatusBean(request,satusBean);
}
/**
*初始化文件上传状态Bean
*/
privateFileUploadStatusinitStatusBean(HttpServletRequest
request){
FileUploadStatussatusBean=newFileUploadStatus();
satusBean.setStatus("正在准备处理");
satusBean.setUploadTotalSize(request.getContentLength());
satusBean.setProcessStartTime(System.currentTimeMillis());
satusBean.setBaseDir(request.getContextPath()+UPLOAD_DIR);
returnsatusBean;
}
/**
*处理文件上传
*/
privatevoidprocessFileUpload(HttpServletRequestrequest,
HttpServletResponseresponse)throws
ServletException,IOException{
DiskFileItemFactoryfactory=newDiskFileItemFactory();
//设置内存缓冲区,超过后写入临时文件
factory.setSizeThreshold();
//设置临时文件存储位置
factory.setRepository(newFile(request.getRealPath("/upload/temp")));
ServletFileUploadupload=newServletFileUpload(factory);
//设置单个文件的最大上传值
upload.setFileSizeMax(0);
//设置整个request的最大值
upload.setSizeMax(0);
upload.setProgressListener(newFileUploadListener(request));
//保存初始化后的FileUploadStatusBean
saveStatusBean(request,initStatusBean(request));
StringforwardURL="";
try{
Listitems=upload.parseRequest(request);
//获得返回url
for(inti=0;iFileItemitem=(FileItem)items.get(i);
if(item.isFormField()){
forwardURL=item.getString();
break;
}
}
//处理文件上传
for(inti=0;iFileItemitem=(FileItem)items.get(i);
//取消上传
if(getStatusBean(request).getCancel()){
deleteUploadedFile(request);
break;
}
//保存文件
elseif(!
item.isFormField()&&item.getName().length()>0){
StringfileName=takeOutFileN