SpringMVC实现文件上传进度条

来源:互联网 发布:推理电影 知乎 编辑:程序博客网 时间:2024/06/05 18:44
  文件上传一般都是基于commons-fileupload组件来实现,SpringMVC的文件上传功能也是在commons-fileupload组件提供的功能上面做了一些包装功能.
  Commons-fileupload组件自带了文件上传进度的监听器,类FileUploadBase提供了它的set方法:
 
public voidsetprogressListener(ProgressListener pListener)
        {
listener= pListener;
        }
ProgressListener是一个接口,我们需要自己实现它的update方法,参数pBytesRead表示已经上传到服务器的字节数,pContentLength表示所有文件的总大小,pItems表示第几个文件:
       protected FileUploadnewFileUpload(FileItemFactory fileItemFactory)
{
return newServletFileUpload(fileItemFactory);
}

我们要做的就是实现ProgressListener类
public classFileUploadListener implements ProgressListener {

private longnum100Ks = 0;
private longtheBytesRead = 0;
private longtheContentLength = -1;
private intwhichItem = 0;
private intpercentDone = 0;
private booleancontentLengthKnown = false;

public voidupdate(long bytesRead, long contentLength, int items){

if(contentLength > -1) {
contentLengthKnown = true;
}
theBytesRead =bytesRead;
theContentLength= contentLength;
whichItem =items;

long nowNum100Ks= bytesRead / 100000;
if (nowNum100Ks> num100Ks) {
num100Ks =nowNum100Ks;
if(contentLengthKnown) {
percentDone =(int) Math.round(100.00 * bytesRead / contentLength);
}

}
}

public int getPercentDone(){
return percentDone;
}
}

SpringMVC没有实现监听器,所以如果要监听的话得自己扩展CommonsMultipartResolver类,在newFileUpload里面加入代码设置自己实现的监听器:
public classCommonsMultipartResolverExt extends CommonsMultipartResolver{

privateHttpServletRequest request;
@Override
protected FileUpload newFileUpload(FileItemFactoryfileItemFactory)
{
ServletFileUpload upload = newServletFileUpload(fileItemFactory); 
upload.setSizeMax(-1); 
if(request!=null)
{
///System.out.println("注入监听");
FileUploadListener uploadProgressListener = newFileUploadListener();
upload.setProgressListener(uploadProgressListener);
HttpSessionsession = request.getSession();
session.setAttribute("uploadProgressListener",uploadProgressListener);
}
returnupload;
}
@Override
publicMultipartHttpServletRequest resolveMultipart(HttpServletRequestrequest) throws MultipartException {
     this.request=request;//获取到request,要用到session
      returnsuper.resolveMultipart(request);
 }
}

建一个servlet用ajax去取进度就可以了
public classProgressServlet extends HttpServlet {
private staticfinal long serialVersionUID = 1L;

public voiddoGet(HttpServletRequest request, HttpServletResponse response)throws IOException {
doPost(request,response);
}

public voiddoPost(HttpServletRequest request, HttpServletResponse response)throws IOException {
response.setContentType("text/html");
response.setHeader("Cache-Control","no-cache");
PrintWriter out= response.getWriter();

HttpSessionsession = request.getSession(true);
if (session ==null) {
out.println("Sorry, session is null"); // justto be safe
return;
}

FileUploadListener uploadProgressListener =(FileUploadListener)session.getAttribute("uploadProgressListener");
if(uploadProgressListener == null) {
out.println("Progress listener isnull");
return;
}
intret=uploadProgressListener.getPercentDone();
System.out.println("new->:"+String.valueOf(ret));
out.println(ret);

}
}

  1. 在Spring的配置文件中添加 Xml代码  
  2. id="multipartResolver"class="net.gkyh.filter.CommonsMultipartResolverExt">  
  3. name="defaultEncoding" value="UTF-8" />  

SpringController

@RequestMapping(value="/AppUpload.action",method=RequestMethod.POST)
publicModelAndView Upload(HttpServletRequest request,HttpServletResponseresponse,
@RequestParam("flag")String flag,ModelMapmodelMap){
try
{
Stringpath=request.getSession().getServletContext().getRealPath("/");
path=path.substring(0,path.length()-1);
 intp=path.lastIndexOf("\");
path=path.substring(0,p);
path=path.replace("\","/");

StringfolderPath=path+"/ftp/upload/";
 
MultipartHttpServletRequestmultipartRequest = (MultipartHttpServletRequest) request; 
          CommonsMultipartFile file =(CommonsMultipartFile)multipartRequest.getFile("filedata");
 // filedata 是表单的名字
                
InputStreamstream = file.getInputStream();  
String fileName= file.getOriginalFilename(); 
//System.out.println(fileName);
         StringfileNameFull = folderPath +fileName; 
        OutputStream bos = new FileOutputStream(fileNameFull); 
         intbytesRead = 0;  
         byte[]buffer = new byte[8192];  
         while((bytesRead = stream.read(buffer, 0, 8192)) != -1) { 
            bos.write(buffer, 0, bytesRead); 
        
 
        bos.close();  
        stream.close();  
  modelMap.put("msg","添加成功"); 
}
catch(Exceptione) {
e.printStackTrace();
}
return newModelAndView("/appupload",modelMap);
}

jsp页面

 <SCRIPT src="../js/jquery-1.3.2.min.js"type="text/javascript"></SCRIPT>
<SCRIPTtype=text/javascript>

functiondoProgressLoop(prog, max, counter) { 
   var x =document.getElementByIdx_x_x('progress-content').innerHTML;
   var y = parseInt(x);
   if (!isNaN(y)) {
   prog = y;
   }
counter =counter + 1;
   if (prog < 100) {
   setTimeout("getProgress()", 1000);
   setTimeout("doProgressLoop(" + prog + "," + max+ "," + counter + ")", 1500);
document.getElementByIdx_x_x('progressBarText').innerHTML= 'upload in progress: ' + prog + '%';
document.getElementByIdx_x_x('progressBarBoxContent').style.width= parseInt(prog) + '%';

   }
}

functiongetProgress() {
$.ajax({
       type:"post",
       dataType:"string",
       url:"ProgressServlet.do",
       data:"",
       success:function (data) {        
         document.getElementByIdx_x_x('progress-content').innerHTML=data;
      },
       error:function (err) {
        document.getElementByIdx_x_x('progressBarText').innerHTML="Errorretrieving progress";
      }
   });
}
  
functionfSubmit()
{
var button =window.document.getElementByIdx_x_x("submitButton");
button.disabled =true;
var max =100;
var prog =0;
var counter= 0;
document.getElementByIdx_x_x('progressBar').style.display= 'block';
document.getElementByIdx_x_x('progressBarText').innerHTML= 'upload in progress: 0%';
getProgress();
doProgressLoop(prog, max,counter);
document.getElementByIdx_x_x("form1").submit();
}
</SCRIPT>
<formname="form1" id="form1" action="AppLoad.action" method="post"enctype="multipart/form-data">

<span>选择文件</span>
<divstyle="padding-bottom:5px;">
<inputtype="file" size="48" name="filedata"id='filedata'>
</div>

<divid="progressBar" style="display:none;"> 

<divid="theMeter"> 
<divid="progressBarText"></div> 

<divid="progressBarBox"style="color:Silver;border-width:1px;border-style:Solid;width:300px;TEXT-ALIGN:left"> 
<divid="progressBarBoxContent" style="background-color:#3366FF;height:15px;width:0%;TEXT-ALIGN:left"></div> 
</div>
<divid="progress-content" style="display:none;"></div>
</div> 
</div>
<INPUT id='submitButton'  tabIndex=3type=button value="提交" onclick='fSubmit();'>
</form>

以下链接是servlet上传文件进度实例,本文使用了部分内容
http://www.avajava.com/tutorials/lessons/how-do-i-display-file-upload-progress-using-the-dojo-progressbar.html?page=1