利用fileupload组件实现掌控上传进度的AJAX Upload

本文介绍了一种利用FileUpload 1.2版本实现文件上传进度显示的方法。通过定义UploadInfo Bean来跟踪上传状态,并使用FileUploadListener监听上传过程,最终通过DWR实现实时进度更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

      前段时间调查了一下可显示进度的文件上传,发现TELIO公司的Pierre-Alexandre发表的《AJAX Upload progress monitor for Commons-FileUpload Example》的实现不错。但是该文中用到的是FileUpload1.1版本,而FileUpload1.2版本提供了处理上传的Listener功能,该功能可大大简化对文件上传得处理,于是对原文中的程序作了一些修改。

服务器端代码:

     首先定义一个保存文件上传状态的Bean,类UploadInfo将其作为服务器端与web客户端之间通信的媒介物。


public   class  UploadInfo
{
    
private long totalSize = 0;
    
private long bytesRead = 0;
    
private long elapsedTime = 0;
    
private String status = "done";
    
private int fileIndex = 0;

    
public UploadInfo()
    
{
    }


    
public UploadInfo(int fileIndex, long totalSize, long bytesRead, long elapsedTime, String status)
    
{
        
this.fileIndex = fileIndex;
        
this.totalSize = totalSize;
        
this.bytesRead = bytesRead;
        
this.elapsedTime = elapsedTime;
        
this.status = status;
    }


    
public String getStatus()
    
{
        
return status;
    }


    
public void setStatus(String status)
    
{
        
this.status = status;
    }


    
public long getTotalSize()
    
{
        
return totalSize;
    }


    
public void setTotalSize(long totalSize)
    
{
        
this.totalSize = totalSize;
    }


    
public long getBytesRead()
    
{
        
return bytesRead;
    }


    
public void setBytesRead(long bytesRead)
    
{
        
this.bytesRead = bytesRead;
    }


    
public long getElapsedTime()
    
{
        
return elapsedTime;
    }


    
public void setElapsedTime(long elapsedTime)
    
{
        
this.elapsedTime = elapsedTime;
    }


    
public boolean isInProgress()
    
{
        
return "progress".equals(status) || "start".equals(status);
    }


    
public int getFileIndex()
    
{
        
return fileIndex;
    }


    
public void setFileIndex(int fileIndex)
    
{
        
this.fileIndex = fileIndex;
    }

}

      然后定义类FileUploadListener,用来监听文件上传的状态。FileUpload1.2版本提供了ProcessListener接口,使开发者可通过FileUploadBase类对象的setProcessListener方法植入自己的Listener。类FileUploadListener实现ProcessListener接口,当文件上传状态有所改变时,将调用其update方法。

public   class  FileUploadListener  implements  ProgressListener
{
    
private HttpServletRequest request;
    
private long delay = 0;
    
private long startTime = 0;

    
public FileUploadListener(HttpServletRequest request, long debugDelay)
    
{
        
this.request = request;
        
this.delay = debugDelay;
        
this.startTime = System.currentTimeMillis();
    }


    
public void update(long pBytesRead, long pContentLength, int pItems) {
        
long delta = (System.currentTimeMillis() - startTime) / 1000;
        request.getSession().setAttribute(
"uploadInfo"new UploadInfo(pItems, pContentLength, pBytesRead,delta,""));
    }

}

      定义UploadMonitor类,并通过dwr的配置,使其和客户端形成映射。

public   class  UploadMonitor
{
    
public UploadInfo getUploadInfo()
    
{
        HttpServletRequest req 
= WebContextFactory.get().getHttpServletRequest();
        
if (req.getSession().getAttribute("uploadInfo"!= null)
            
return (UploadInfo) req.getSession().getAttribute("uploadInfo");
        
else
            
return new UploadInfo();
    }

}

     对类UploadInfo和UploadMonitor类在dwr.xml中进行相应的配置。

< dwr >
    
< allow >
        
< create creator = " new "  javascript = " UploadMonitor " >
            
< param name = " class "  value = " be.telio.mediastore.ui.upload.UploadMonitor " />
        
</ create >
        
< convert converter = " bean "  match = " be.telio.mediastore.ui.upload.UploadInfo " />
        
        
< create creator = " new "  javascript = " ReverseAjaxDemo "  scope = " application " >
            
< param name = " class "  value = " be.telio.mediastore.ui.upload.ReverseAjaxDemo " />
        
</ create >
    
</ allow >
</ dwr >

Web客户端代码:

      为了说明问题,只提供了最基本的实现,并去掉了多余的代码。

      前台采用JSP的方式,操作界面(index.jsp):

......
< form  action ="upload.jsp"  enctype ="multipart/form-data"  method ="post"  onsubmit ="startProgress()" >
        
< input  class ="default"  type ="file"  id ="file1"  name ="file1" />< br />
        
< input  type ="submit"  value ="begin upload"  id ="uploadbutton" />
        
< div  id ="progressBar"  style ="display: none;" >
            
< div  id ="theMeter" >
                
< div  id ="progressBarText" ></ div >
                
< div  id ="progressBarBox" >
                    
< div  id ="progressBarBoxContent" ></ div >
                
</ div >
            
</ div >
        
</ div >
    
</ p >
</ form >
......

      因为这个例子重点为了说明控制文件上传的状态,所以代码中再对请求解析后没有做进一步的操作。如果想对上传得文件进一步操作,可先获得upload对象的返回值,它是一个List,其中存储的是FileItem对象,该对象可以是form表单域或是上传文件file域,FileItem类提供了一些方法可获得上传对象的相关信息,具体可参考commons fileupload组件的API文档。下面代码为upload.jsp中的主要部分:

......
<%
    DiskFileItemFactory factory 
= new DiskFileItemFactory();
    ServletFileUpload upload 
= new ServletFileUpload(factory);
    upload.setProgressListener(
new FileUploadListener(request, 30));
    upload.parseRequest(request);
%>
......

      至此,只需在客户端循环发送请求即可。upload.js中的主要代码如下:


function  refreshProgress()  {
    UploadMonitor.getUploadInfo(updateProgress);
}


function  updateProgress(uploadInfo)  {
    
var progressPercent = Math.ceil((uploadInfo.bytesRead / uploadInfo.totalSize) * 100);
    document.getElementById(
'progressBarText').innerHTML = 'upload in progress: ' + progressPercent + '%';
    document.getElementById(
'progressBarBoxContent').style.width = parseInt(progressPercent * 3.5+ 'px';
    window.setTimeout(
'refreshProgress()'1000);
    
return true;
}


function  startProgress()  {
    document.getElementById(
'progressBar').style.display = 'block';
    document.getElementById(
'progressBarText').innerHTML = 'upload in progress: 0%';
    document.getElementById(
'uploadbutton').disabled = true;

    
// wait a little while to make sure the upload has started ..
    window.setTimeout("refreshProgress()"1500);
    
return true;
}

     


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值