JavaWeb学习笔记3——带进度条的文件上传

本项目代码的运行需要用到commons-fileupload-1.3.3和commons-io-2.6两个jar包,下载地址:

https://download.csdn.net/download/h2503652646/10654627

首先我们需要创建两个Class,即UploadListener和UploadStatus,一个Servlet,即ProgressUploadServlet,和一个jsp文件ProgressUpload,如图

话不多说,直接上代码。

上传监听器

UploadListener.java的代码

package com.test.progressUpload;

import org.apache.commons.fileupload.ProgressListener;

public class UploadListener implements ProgressListener{
	
	private UploadStatus status;
	
	public UploadListener(UploadStatus status){
		
		this.status=status;
	}
	
	public void update(long bytesRead,long contentLength,int items){
		
		status.setBytesRead(bytesRead);  //已读取的数据长度
		status.setContentLength(contentLength);  //文件总长度
		status.setItems(items);       //正在上传第几个文件
	}

}

UploadStatus.java的代码

package com.test.progressUpload;

public class UploadStatus {
	
	private long bytesRead;
	private long contentLength;
	private int items;
	private long startTime=System.currentTimeMillis();
	
	public long getBytesRead(){
		
		return bytesRead;
	}
	
	public void setBytesRead(long bytesRead){
		
		this.bytesRead =bytesRead;
	}
	
	public long getContentLength(){
		
		return contentLength;
	}
	
	public void setContentLength(long contentLength){
		
		this.contentLength =contentLength;
	}
	
	public int getItems(){
		
		return items;
		
	}
	
	public void setItems(int items){
		
		this.items =items;
	}
	
	public long getStartTime(){
		
		return startTime;
	}
	
	public void setStartTime(long startTime){
		
		this.startTime =startTime;
	}
	

	

}

监听和读取上传进度

上传文件是用的doPost()方法,读取上传进度用doGet()方法。

ProgressUploadServlet.java的代码

package com.test.progressUpload;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class ProgressUploadServlet extends HttpServlet {

	/**
	 * Constructor of the object.
	 */
public ProgressUploadServlet() {
	super();
}

/**
	 * Destruction of the servlet. <br>
	 */
public void destroy() {
	super.destroy(); // Just puts "destroy" string in log
	// Put your code here
}

/**
	 * The doGet method of the servlet. <br>
	 *
	 * This method is called when a form has its tag value method equals to get.
	 * 
	 * @param request the request send by the client to the server
	 * @param response the response send by the server to the client
	 * @throws ServletException if an error occurred
	 * @throws IOException if an error occurred
	 */
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	//禁止浏览器缓存
	response.setHeader("Cache-Control", "no-store");
	response.setHeader("Pragrma", "no-cache");
	response.setDateHeader("Expires", 0);
	 
	UploadStatus status =(UploadStatus)request.getSession(true).getAttribute("uploadStatus");  //从Session读取数据
	
	
	if(status==null){
		
		response.getWriter().println("没有上传的信息");
		return;
	}
	
	//各种上传信息
	long startTime=status.getStartTime();
	long currentTime=System.currentTimeMillis();
	long time =(currentTime-startTime)/1000+1;
	
	double velocity =((double)status.getBytesRead())/(double)time;
	double totalTime=status.getContentLength()/velocity;
	double timeLeft=totalTime-time;
	int percent=(int)(100*(double)status.getBytesRead()/(double)status.getContentLength());
	double length =((double)status.getBytesRead())/1024/1024;
	double totalLength=((double)status.getContentLength())/1024/1024;
	
	String value =percent+"||"+length+"||"+totalLength+"||"+velocity+"||"
	              +time+"||"+totalTime+"||"+timeLeft+"||"+status.getItems();
	
	
	
	response.getWriter().println(value);  //输出给浏览器进度条
	

	
	
}

/**
	 * The doPost method of the servlet. <br>
	 *
	 * This method is called when a form has its tag value method equals to post.
	 * 
	 * @param request the request send by the client to the server
	 * @param response the response send by the server to the client
	 * @throws ServletException if an error occurred
	 * @throws IOException if an error occurred
	 */
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	UploadStatus status =new UploadStatus();
	UploadListener listener =new UploadListener(status);
	
	request.getSession(true).setAttribute("uploadStatus", status);  //把状态放到Session里
	
	ServletFileUpload upload =new ServletFileUpload(new DiskFileItemFactory());  //解析
	upload.setProgressListener(listener);
	
	try{
		List itemList =upload.parseRequest(request);  //提交的所有参数
		
		for(Iterator it = itemList.iterator();it.hasNext();){
			
			
			FileItem item =(FileItem) it.next();
			
			if(item.isFormField()){          //如果是表单数据
				
				System.out.println("FormField:"+item.getFieldName()+"="+item.getString());
			}else {                         //否则是文件
				
				System.out.println("File:"+item.getName());
				
				String fileName =item.getName().replace("/", "\\");
				fileName =fileName.substring(fileName.lastIndexOf("\\"));
				
				File saved =new File("G:\\upload_test",fileName);
				
				saved.getParentFile().mkdirs();  //保证路径存在
				
				InputStream ins =item.getInputStream();
				OutputStream ous =new FileOutputStream(saved);
				
				//缓存写入
				byte[] tmp =new byte[1024];
				int len=-1;
				while((len=ins.read(tmp))!=-1){
					ous.write(tmp,0,len);
					
				}
				
				ous.close();
				ins.close();
				response.getWriter().println("已保存文件:"+saved);
				
			
			}
						
		}
		
	
	}catch(Exception e){
		
		response.getWriter().println("上传发生错误: "+e.getMessage());
	}


}

/**
	 * Initialization of the servlet. <br>
	 *
	 * @throws ServletException if an error occurs
	 */
public void init() throws ServletException {
	// Put your code here
}

}

显示上传进度

ProgressUpload.jsp的代码

<%@ page language="java" contentType="text/html; charset=UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
  <head>
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
   <title>Insert title here</title>
   <style type="text/css">
   body,td,dib {font-size: 12px;font-family:宋体;}
   #progressBar{width:400px;height:12px;background:#FFFFFF;border:1px soild #000000; padding:1px;}
   #progressBarItem{width:%30;height:100%;background:#FF0000;}
   </style>
   </head>  
   <body>
   <iframe name=uploadiframe width=0 height=0></iframe>
   
   <form action="servlet/ProgressUploadServlet" method ="post" enctype="multipart/form-data" target="uploadiframe" onsubmit="showStatus(); ">
   
   <input type="file" name="file1" style="width: 350px; "><br/>
   <input type="file" name="file2" style="width: 350px; "><br/>
   <input type="file" name="file3" style="width: 350px; "><br/>
   <input type="file" name="file4" style="width: 350px; ">
   <input type="submit" value="开始上传" id="btnSubmit"></form>
   
   <div id="status" style="display: none;">
     上传进度条:
     <div id="progressBar"><div id="progressBarItem"></div></div>
     <div id="statusInfo"></div>
   </div>
   
   
   
   <script type="text/javascript">
   var finished =true;        //上传是否结束
   function $(obj){
   
         return document.getElementById(obj);   //快速返回id为obj的HTML对象
   }
   
   
   function showStatus(){
   
           finished =false;
           $('status').style.display ='block';        //显示进度条
           $('progressBarItem').style.width='1%';     //将进度条置为1%
           $('btnSubmit').disable =true;              //把提交按钮置灰
           setTimeout("requestStatus()",1000);        //1秒钟后执行requestStatus()方法
   }
   
   
   function requestStatus(){                          //向服务器请求上传进度信息
                                                      //若已经上传完成,则返回
           if(finished)  return;
           
           var req =createRequest();
           req.open("GET","servlet/ProgressUploadServlet");      //设置请求路径
           req.onreadystatechange=function(){callback(req);}
           
           req.send(null);
           setTimeout("requestStatus()",1000);           //1秒钟后重新请求
   

   }
      
   
   function createRequest(){
            
            if(window.XMLHttpRequest){                 //Netscape浏览器
                      
                      return new XMLHttpRequest();
            
            }else{                                   //IE浏览器
                      try{
                          
                          return new ActiveXObject("Msxm12.XMLHTTP");
                      
                      }catch(e){
                      
                          return new ActiveXObject("Microsoft.XMLHTTP");
                      }
            
            }
     
   }
   
   
   function callback(req){          //刷新进度条
   
             if(req.readyState==4){
                   
                   if(req.status !=200){
                   
                         debug("发生错误。  req.status: "+ req.status +"");
                         return;
             
                   }
                   
             
                   debug("status.jsp 返回值: "+req.responseText);
                   var ss=req.responseText.split("||");
                   
                   $('progressBarItem').style.width =''+ss[0] + '%';
                   $('statusInfo').innerHTML ='已完成百分比: '+ss[0] +'%<br />已完成数(M):'+ss[1]+'<br/>文件总长度(M):'+
                                   ss[2]+'<br/>传输速率(K):'+ss[3]+'<br/>已用时间(S):'+ss[4]+'<br/>估计总时间(S):'+
                                   ss[5]+'<br/>估计剩余时间(S):'+ss[6]+'<br/>正在上传第几个文件:'+ss[7];
                                   
                   
                   
                   if(ss[1]==ss[2]){
                   
                        finished =true;
                        $('statusInfo').innerHTML += "<br/><br/><br/>上传已完成。";
                        $('btnSubmit').disabled=false;
                   
                   }
            
             }
 
   }
  
    function debug(obj){              //显示调试信息
    
          var div =document.createElement("DIV");
          div.innerHTML ="[debug]: "  +obj;
          document.body.appendChild(div);
    
    
    }
    
</script>
</body>
</html>

在浏览器中输入:http://localhost:8080/ProgressUpload/ProgressUpload.jsp  回车

运行效果如图所示:

猜你喜欢

转载自blog.csdn.net/h2503652646/article/details/82556468