`

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

分享到:
评论

相关推荐

    关于zhaobq 的Ajax+servlet上传进度条的改进

    感谢zhaobq给我们提供了Ajax+servlet实现上传进度条。但此代码运行时会有一点小问题:1、点上传时会打开另一个IE页面,我采用了一个iframe进行隐藏。2、有时看不见进度条,特别是小文件时,在此我采用了线程sleep,...

    JAVA实现模拟导入数据/上传文件进度条

    总的来说,实现一个文件上传进度条功能需要前后端的协同工作,通过Servlet处理文件上传,JSP提供交互界面,jQuery和Ajax负责前端与后端的通信,实时更新进度条状态。这个过程涉及到了多种技术的综合运用,对于提升...

    jsp上传实现进度条

    为了实现实时进度条,我们需要使用异步请求,例如AJAX,来分块上传文件并更新进度。 1. **HTML表单**:在JSP页面中创建一个包含`enctype="multipart/form-data"`的表单,以便支持文件上传。设置一个隐藏的iframe...

    基于ajax实现文件上传并显示进度条

    下面给大家分享下基于ajax实现文件上传并显示进度条。在jsp部分,需要设计一个表单,form的属性添加 enctype=”multipart/form-data”,设计一个iframe,作为隐藏。form的target等于iframe的name; 在servlet部分:...

    jsp无刷新上传文件

    本示例以“jsp无刷新上传文件”为主题,结合使用了iframe、AJAX以及jsp技术,实现了这一功能。以下是相关的知识点详解: 1. **iframe(内联框架)**:iframe允许在HTML文档中嵌入另一个HTML文档,常用于实现页面的...

    java文件上传可以预览

    首先,你需要在项目中引入这个库,然后创建一个`Servlet`来处理上传请求,解析`Part`对象,并将文件保存到服务器的某个目录。 2. **使用Spring MVC**:如果你的项目基于Spring框架,Spring MVC提供了一套完整的文件...

    java文件上传

    11. **进度条显示**:为了让用户有更好的交互体验,可以实现文件上传进度条,这通常需要服务器端支持,如提供进度信息的API。 12. **前端实现**:前端可能使用JavaScript库如jQuery或现代框架如React、Vue等,配合...

    fancyupload批量上传文件

    4. **文件上传流程**:在FancyUpload中,文件上传通常涉及以下步骤:用户选择文件,FancyUpload通过Ajax或IFrame技术分块或整体发送文件到服务器,服务器接收到文件后进行存储,并可能返回确认信息或错误消息。...

    springmvc文件上传

    Plupload是一款多浏览器、多模式(Flash、HTML5、Silverlight、iframe)的文件上传插件,它提供了丰富的上传功能,如多文件选择、进度条显示、断点续传等。将Spring MVC与Plupload结合,可以构建一个高效、用户体验...

    java写的图片上传代码

    然后,在Servlet中,可以通过HttpServletRequest对象的getParts()方法获取到上传的文件。 接着,我们需要实例化MultipartFile对象,并检查文件大小、类型等,确保上传的文件符合预期。确认无误后,可以将图片保存到...

    plupload.zip

    Plupload提供了一套完整的文件上传解决方案,包括拖拽上传、多文件同时上传、进度条显示、断点续传等功能。它通过JavaScript编写,能够适应各种浏览器环境,确保了良好的兼容性。此外,Plupload还提供了丰富的API和...

    用iframe实现不刷新整个页面上传图片的实例

    经常用到上传图片即时预览的功能,实现方式很多,用flash+js...3. 如果用到要进度条等效果,就在表单提交后,在servlet一端输出进度条,然后一直发送调用js脚本,及时改变页面内容。其他功能诸如取消等功能可以参考推送

    jQuery-File-Upload-9.19.1.zip_jqueryfileupload jsp

    2. **进度条显示**:在文件上传过程中,提供实时的上传进度反馈,提升用户体验。 3. **预览与缩略图**:支持图片等媒体文件的预览,显示缩略图,增强交互性。 4. **跨域上传**:支持CORS(跨源资源共享),使得文件...

    jsp+ajax实现无刷新上传文件的方法

    在这个页面中,我们可以使用Servlet或自定义Java类(如`UploadUtil.java`)来处理文件上传。文件上传通常涉及到解析请求中的多部分数据,将文件保存到服务器,并可能进行一些验证和错误处理。例如,`UploadUtil.java...

    java jquery 单个和多个图片上传的例子

    - 在Java中,我们需要创建一个Servlet或Controller来接收并处理上传的文件。 - 验证上传的文件大小、类型等是否符合预期。 - 将文件保存到服务器的指定目录,并返回成功或失败的响应。 4. **服务器端响应处理**...

    iframereload.rar_Java编程_Java_

    在描述中提到的“加载效果”,是指在Iframe内容真正加载完成之前展示的一种视觉反馈,比如一个加载动画或进度条,这样用户可以知道页面正在处理中,避免出现空档期的困惑。这种效果通常用JavaScript和CSS实现,配合...

Global site tag (gtag.js) - Google Analytics