iframe+servlet文件上传实时进度条

后台:

package com.scott.uploadfile;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
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.FileUploadException;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
/**
 * @author scott.wanglei
 * @since  2009-1-8
 * 使用多线程实现文件进度的显示
 */
public class UploadFile extends HttpServlet {
	private static final long serialVersionUID = 4030816613803833495L;
	//同步散列表保存文件上传进度类的引用
	private ConcurrentHashMap<String,Progress> chp = new ConcurrentHashMap<String,Progress>();
	public UploadFile() {
		super();
	}
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
             this.doPost(request, response);
	}
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		    
		    
		     response.setContentType("text/html;charset=UTF-8");
		     response.setHeader("pragma", "no-cache");
		     response.setHeader("cache-control", "no-cache");
		     response.setHeader("expires", "0");
		     
		     if(request.getContentType() == null){
		    	 Progress p = new Progress(); 
		    	 //根据上request对象产生的String的hashcode值做为key值
		    	 String key = Integer.toString(request.toString().hashCode());
		    	 //根据key值储存当前文件的进度对象引用
		    	 chp.put(key, p);
		    	 //把key传回并发起上传文件的请求
		    	 this.sendMsg(response,"parent.uploadFile('"+key+"')");
		    	 //上传线程没有开始时候阻塞更新线程
		    	 while(true){
		    		 if(p.getLength() != 0)
		    			 break;
		    	 }
		    	 long temp = 0;
		    	 while(! p.isComplete){
		    		 if(temp != p.getCurrentLength()){
		    			 temp = p.getCurrentLength();
		    			 //更新客户端进度
		    			 this.sendMsg(response, "parent.upload('"+temp+"','"+p.getLength()+"')");
		    			 
		    		 }
		    	 }
		     } 
		     else if(request.getContentType().indexOf("multipart/form-data") > -1){
		    	   //上传线程开始执行
		    	   String key = request.getParameter("key");
		    	   Progress p = chp.get(key);
		    	   if(p != null){
		    	      p.setLength(request.getContentLength());
		    	      this.startUploadFile(request,response, p,request.getRealPath("/"),key);
		    	      chp.remove(key);
		    	   }
		    	   else{
		    		   this.sendMsg(response, "alert('Progress is null,k1 is not equal k2')");
		    		   
		    	   }
		    	  
		     } 
		     else {
                 this.sendMsg(response, "alert('ContentType is not correctly')");   
                 
		     }
		     
		     
	}
	
	//上传文件
	private void startUploadFile( HttpServletRequest request, HttpServletResponse response,Progress p, 
			String path,String key)
	        throws IOException{
	      
			   //设置上传工厂
			   DiskFileItemFactory factory = new DiskFileItemFactory();	
			   factory.setRepository(new File(path));
			   //阀值,超过这个值才会写到临时目录
			   factory.setSizeThreshold(1024*1024*10); 
			   ServletFileUpload upload = new ServletFileUpload(factory);
			   //最大上传限制
			   upload.setSizeMax(1024*1024*200);
			   //设置监听器监听上传进度
			   upload.setProgressListener(p);
			   List<FileItem> items = null;
	           try {
	        	   items = upload.parseRequest(request);
			   } catch (FileUploadException e) {
				e.printStackTrace();
				this.errorAndStorp(response, "alert('FileUploadExeception happened')", p,key);
			   }
			   
			   for(Iterator<FileItem> it = items.iterator();it.hasNext();){
				   FileItem item = it.next();
				   if(item.isFormField()){
					   //处理表单域
				   }
				   else{
					   try {
						   FileOutputStream  fos = new FileOutputStream(path+URLEncoder.encode(item.getName(),"utf-8"));
						   if(item.isInMemory()){//文件全在内存中
							   fos.write(item.get());
							   p.setComplete(true);
						   }
						   else{
							   InputStream is = item.getInputStream();
							   byte[] buffer = new byte[1024];
							   int len;
							   while((len = is.read(buffer)) > 0){
								   fos.write(buffer, 0, len);
							   }
							   p.setComplete(true);
							   is.close();
							   fos.close();   
						   }
					   } catch (Exception e) {
						   e.printStackTrace();
						   this.errorAndStorp(response, "alert('Exception happened')", p,key);} 			     
				   }
			   }
	}
	
	//上传线程一旦出现意外,就让progress出于完成状态以终止向客户端发送信息的线程
	private void errorAndStorp(HttpServletResponse response,String script,
			Progress p,String key) 
	       throws IOException{
		
		p.setComplete(true);
		chp.remove(key);
		this.sendMsg(response, script);
	}
	
	//向客户端发送数据
	private void sendMsg(HttpServletResponse response,String script) throws IOException{
	  PrintWriter out =	response.getWriter();
	  out.println("<script type='text/javascript'>" +script +"</script>");
	  //ie太拽了发送的字节少了它根本不掉你
      out.println("---------------------------------------------------");
      out.println("---------------------------------------------------");
      out.println("---------------------------------------------------");
      out.println("---------------------------------------------------");
	  out.flush();
	}
	
    //存放文件上传进度
    private static class Progress implements ProgressListener{
    	
    	private  long length = 0;//文件总长度
    	private long currentLength = 0;//已上传的文件长度
    	private boolean isComplete = false;//上传是否完成
    	
    	//实现监听器方法实时更新进度属性
		public void update(long bytesRead, long contentLength, int items) {
			currentLength = bytesRead;
		}
    	
    	public Progress(){}
    	
		public long getLength() {
			return length;
		}
		public void setLength(int l){
			this.length = l;
		}
		public long getCurrentLength() {
			return currentLength;
		}
		
		public void setCurrentLenght(int cl){
			this.currentLength = cl;
		}
		public boolean isComplete() {
			return isComplete;
		}
		public void setComplete(boolean isComplete) {
			this.isComplete = isComplete;
		}
    }
}

 前台

<%@ page language="java"  pageEncoding="utf-8"%>  
<%  
String path = request.getContextPath();  
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
%>  
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
<html>  
  <head>  
    <base href="<%=basePath%>">  
      
    <title>ajax显示上传文件进度</title>  
      
    <meta http-equiv="pragma" content="no-cache">  
    <meta http-equiv="cache-control" content="no-cache">  
    <meta http-equiv="expires" content="0">      
    <!-- 
    <link rel="stylesheet" type="text/css" href="styles.css" mce_href="styles.css"> 
    -->  
    <mce:style type="text/css"><!--  
        iframe{  
            border:0;  
        }  
        #p_out{  
          width:200px;  
          height:12px;  
          margin:10px 0 0 0;  
          padding:1px 1px 1px 1px;  
          font-size:10px;  
          border:solid #d4e4ff 1px;  
        }  
        #p_in{  
          width:0%;  
          height:100%;  
          background-color:#d4e4ff;  
          margin:0;  
          padding:0;  
        }  
        #dis{  
          margin:0;  
          padding:0;  
          text-align:center;  
          font-size:12px;  
          height:12px;  
          width:200px;  
        }  
      
--></mce:style><mce:style type="text/css" mce_bogus="1"><!--  
        iframe{  
            border:0;  
        }  
        #p_out{  
          width:200px;  
          height:12px;  
          margin:10px 0 0 0;  
          padding:1px 1px 1px 1px;  
          font-size:10px;  
          border:solid #d4e4ff 1px;  
        }  
        #p_in{  
          width:0%;  
          height:100%;  
          background-color:#d4e4ff;  
          margin:0;  
          padding:0;  
        }  
        #dis{  
          margin:0;  
          padding:0;  
          text-align:center;  
          font-size:12px;  
          height:12px;  
          width:200px;  
        }  
      
--></mce:style><style type="text/css" mce_bogus="1" mce_bogus="1">       iframe{  
            border:0;  
        }  
        #p_out{  
          width:200px;  
          height:12px;  
          margin:10px 0 0 0;  
          padding:1px 1px 1px 1px;  
          font-size:10px;  
          border:solid #d4e4ff 1px;  
        }  
        #p_in{  
          width:0%;  
          height:100%;  
          background-color:#d4e4ff;  
          margin:0;  
          padding:0;  
        }  
        #dis{  
          margin:0;  
          padding:0;  
          text-align:center;  
          font-size:12px;  
          height:12px;  
          width:200px;  
        }  
    </style>  
  </head>  
    
  <body>  
    <form id="uploadfile_form" name="uploadfile_form" enctype="multipart/form-data"  
     method="post" target="uploadfile_iframe">  
          
        <input type="file" name="file" />  
        <br><br>  
        <button onclick="progress()">提交</button>  
          
        <div id="p_out"><div id="p_in"></div></div>  
        <div id="dis"></div>  
    </form>  
    <iframe width="0px" height="0px" id="uploadfile_iframe" name="uploadfile_iframe" src="javascript:void(0)" ></iframe>  
    <iframe width="0px" height="0px" id="progress_iframe" name="progress_iframe" src="javascript:void(0)" ></iframe>  
  </body>  
    
  <script type="text/javascript"> 
    function progress(){
        document.getElementById('progress_iframe').src = 'myFileUpload';  
        document.getElementById('dis').innerHTML = '初始化数据...';  
    }  
      
    function uploadFile(k){
    	console.log("k="+k);
        document.forms[0].action = 'myFileUpload?key='+k;  
        document.forms[0].submit();  
    }  
      
    function upload(len,total){
    	console.log("len="+len+"total="+total);
        document.getElementById('p_in').style.width = (Math.round(len/total*100))+'%';  
        document.getElementById('dis').innerHTML = len+'/'+total+' Byte';  
    }  
      
    
</script>  
</html>  

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <display-name></display-name>	
  
  <servlet>
  	<servlet-name>myFileUpload</servlet-name>
  	<servlet-class>com.scott.uploadfile.UploadFile</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>myFileUpload</servlet-name>
  	<url-pattern>/</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

 导入commons-fileupload-1.3.1.jar,commons-io-2.2.jar

注:原文地址http://blog.csdn.net/tom_221x/article/details/3777064

猜你喜欢

转载自forsave.iteye.com/blog/2289523
今日推荐