ajax上传文件带进度条

此案例使用ajax + springmvc

 1、第一种方式

第一种使用的是ajax formData,这种方式,ie9不支持formData,所以从中方式不使用ie9,(ie10 and ie10+ 没有测试)

html:

<style>
	#prograssbarBorder{
		width:500px;
		height:30px;
		border:1px solid #B2B2B2;
		border-radius:50px 50px 50px 50px;
	}
	#prograssbar{
		width:0px;
		height:30px;
		background:#00D328;
		border-radius:50px 50px 50px 50px;
	}
</style>

<script>
	var xhr;
	if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
		xhr = new XMLHttpRequest();
	} else {// code for IE6, IE5
		xhr = new ActiveXObject("Microsoft.XMLHTTP");
	}

	$(function() {
		$("#testInfoForm").submit(function() {

			var fileData = document.getElementById('uploadFile').files[0];
			var formData = new FormData();
			xhr.open('post', 'testSaveUpload.do', true);
			xhr.onreadystatechange = function() {
				if (this.readyState == 4) { 
					//0: 请求未初始化
					//1: 服务器连接已建立
					//2: 请求已接收
					//3: 请求处理中
					//4: 请求已完成,且响应已就绪
					document.getElementById('prograssbar').style.width = 100 + '%';
					document.getElementById('precent').innerHTML = Math.floor(100) + '%';
				}
			}
			xhr.upload.onprogress = function(ev) {
				if (ev.lengthComputable) {
					var precent = 100 * ev.loaded / ev.total;
					if(100 == precent){
						document.getElementById('prograssbar').style.width = 99.9 + '%';
						document.getElementById('precent').innerHTML = Math.floor(99.9) + '%';
					}else{
						document.getElementById('prograssbar').style.width = precent + '%';
						document.getElementById('precent').innerHTML = Math.floor(precent) + '%';
					}
					
					
				}
			}
			formData.append('uploadFile', fileData);
			xhr.send(formData);

			return false;
		});
	})
</script>



<div>

	<div id="prograssbarBorder">
        <div id="prograssbar"></div>
    </div>
    <span id="precent"></span><br/>
    
    
	<form id="testInfoForm" enctype="multipart/form-data">
		<div>
			<table>
				<tr>
					<td>上传文件</td>
					<td><input type="file" id="uploadFile" name="uploadFile"
						class="InputStyle" /> *</td>
				</tr>

			</table>
		</div>
		<div>
			<input type="submit" id="saveBtn" />
		</div>
	</form>
</div>

 

 

2、第二种方式

 

第二种方式使用ajaxform,使用ajxasubmit来处理,这种方式支持ie9(仅仅支持文件的上传,不支持进度条显示)同理 ie10 and ie10+ 没有试验。

 

html:

注意:第二中方式需要引入 juqery.form.js

<script type="text/javascript" src="js/jquery.form.js"></script>
<style>
#prograssbarBorder {
	width: 500px;
	height: 30px;
	border: 1px solid #B2B2B2;
	border-radius: 50px 50px 50px 50px;
}

#prograssbar {
	width: 0px;
	height: 30px;
	background: #00D328;
	border-radius: 50px 50px 50px 50px;
}
</style>

<script>
	
	
	function onprogress(ev){
		if (ev.lengthComputable) {
			var precent = 100 * ev.loaded / ev.total;
			if(100 == precent){
				document.getElementById('prograssbar').style.width = 99.9 + '%';
				document.getElementById('precent').innerHTML = Math.floor(99.9) + '%';
			}else{
				document.getElementById('prograssbar').style.width = precent + '%';
				document.getElementById('precent').innerHTML = Math.floor(precent) + '%';
			}
		}
    }
	
	function onreadystatechange(ev){
		if (this.readyState == 4) { 
			//0: 请求未初始化
			//1: 服务器连接已建立
			//2: 请求已接收
			//3: 请求处理中
			//4: 请求已完成,且响应已就绪
			document.getElementById('prograssbar').style.width = 100 + '%';
			document.getElementById('precent').innerHTML = Math.floor(100) + '%';
		}
    }
	
	
	$(function() {
		
		
		/* $('#testInfoForm').ajaxForm(function(){
			 
			 
		}); */
		$("#testInfoForm").submit(function() {
			var option = {
				url : 'testSaveUpload.do',
				type : "post", 
				async : true,  //必须是异步,否则进度条不会显示
				
				success : function(data) {
					var aa = "aaa";
				},
			 	xhr : function(){
	                var xhr = $.ajaxSettings.xhr();
	                if(onprogress && xhr.upload) {
	                    xhr.upload.addEventListener("progress" , onprogress, false);
	                }
	                xhr.addEventListener("readystatechange",onreadystatechange,false);
	                return xhr;
	                
	            },
	            
			};
			
			$("#testInfoForm").ajaxSubmit(option);
			

			return false;
		});
	})
</script>



<div>

	<div  id="prograssbarBorder">
		<div  id="prograssbar"></div>
	</div>
	<span id="precent"></span><br />


	<form id="testInfoForm" enctype="multipart/form-data">
		<div>
			<table>
				<tr>
					<td>上传文件</td>
					<td><input type="file" id="uploadFile" name="uploadFile"
						class="InputStyle" /> *</td>
				</tr>

			</table>
		</div>
		<div>
			<input type="submit" id="saveBtn" />
		</div>
	</form>
</div>

 

 

后台:

@RequestMapping(value="testSaveUpload") 
	public void testSaveUpload(HttpServletRequest request,HttpServletResponse response) throws Exception{
		response.setContentType("text/html");
		MultipartHttpServletRequest multiPartRequest =  (MultipartHttpServletRequest) (request instanceof MultipartHttpServletRequest ? request : null) ;
		MultipartFile uploadFile = multiPartRequest.getFile("uploadFile");
		String originalFilename = uploadFile.getOriginalFilename();
		String subfix = originalFilename.substring(originalFilename.lastIndexOf("."), originalFilename.length());
		File filePaht = new File("D:\\TestM\\Exam\\"+UUID.randomUUID().toString()+subfix);
		uploadFile.transferTo(filePaht);
		response.setStatus(HttpServletResponse.SC_OK);
		response.getOutputStream().println("aaa");
	}
	

 

 

 3、第三种方式

 第三种方式,使用前台不断给后台发送请求,后台利用线程,将已经读取的文件返回给前台这种方式,兼容ie9。同样用到了 ajaxform,使用ajxasubmit提交。需要引入 juqery.form.js

html:

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ include file="/common/common.jsp"%>
<%@ include file="/common/tips.jsp"%>

<script type="text/javascript" src="js/jquery.form.js"></script>
<style>
#prograssbarBorder {
	width: 500px;
	height: 30px;
	border: 1px solid #B2B2B2;
	border-radius: 50px 50px 50px 50px;
}

#prograssbar {
	width: 0px;
	height: 30px;
	background: #00D328;
	border-radius: 50px 50px 50px 50px;
}
</style>

<script>
	
	
	$(function() {
		
		$("#testInfoForm").submit(function() {
			
			var option = {
				url : 'testSaveUpload.do',
				type : "post", 
				success : function(data) {
					// requestStatus+",,,"+threadId+",,,"threadStatus
					var requestStatus = data.split(",,,")[0];
					var currentThreadId = data.split(",,,")[1];
					var threadStatus = data.split(",,,")[2];
					var totalSize = data.split(",,,")[3];
					var readSize = data.split(",,,")[4];
					if(requestStatus == 'running'){//未完成,正在运行
						$("#threadId").val(currentThreadId);
						var precent = 100 * readSize / totalSize;
						document.getElementById('prograssbar').style.width = precent + '%';
						document.getElementById('precent').innerHTML = Math.floor(precent) + '%';
					}else if(requestStatus == 'success'){ //上传完成,成功
						$("#threadId").val("");
						clearInterval(myInterval);
						document.getElementById('prograssbar').style.width = 100 + '%';
						document.getElementById('precent').innerHTML = Math.floor(100) + '%'; 
					}else if(requestStatus == 'failed'){ //上传失败
						$("#threadId").val("");
						clearInterval(myInterval);
					}else{
						$("#threadId").val("");
						clearInterval(myInterval);
					}
				},
				error : function (){
					$("#threadId").val("");
					clearInterval(myInterval);
				},
	            
			};
			
			
			var myInterval =setInterval(function(){
				var threadId = $("#threadId").val();
				$("#testInfoForm").ajaxSubmit(option);
			},500);
	
			return false;
		});
			
			
			
		
		
		
		
		
		
		
		
		
		
		
	})
</script>



<div>

	<div  id="prograssbarBorder">
		<div  id="prograssbar"></div>
	</div>
	<span id="precent"></span><br />

	
	<form id="testInfoForm" enctype="multipart/form-data">
	
		<input type="hidden" id="threadId" name="threadId" /> 
		<div>
			<table>
				<tr>
					<td>上传文件</td>
					<td><input type="file" id="uploadFile" name="uploadFile"
						class="InputStyle" /> *</td>
				</tr>

			</table>
		</div>
		<div>
			<input type="submit" value="提交" id="saveBtn" />
		</div>
	</form>
</div>
 

 

 

后台:

 

 

@RequestMapping(value="testSaveUpload") 
	public void testSaveUpload(HttpServletRequest request,HttpServletResponse response,String threadId) throws Exception{
		MultipartHttpServletRequest multiPartRequest =  (MultipartHttpServletRequest) (request instanceof MultipartHttpServletRequest ? request : null) ;
		MultipartFile uploadFile = multiPartRequest.getFile("uploadFile");
		String originalFilename = uploadFile.getOriginalFilename();
		String subfix = originalFilename.substring(originalFilename.lastIndexOf("."), originalFilename.length());
	
		InputStream input = uploadFile.getInputStream();
		//总大小
		long totleSize = uploadFile.getSize();
		System.out.println("总大小:---》"+totleSize);
		
		long readSum = 0l;
		if(StringUtils.isNotBlank(threadId)){ //当前线程正在运行
			ReadFileThread readFileThread = (ReadFileThread) ConstantMap.constantMap.get(threadId);
			//获取已读大小
			long readSize = readFileThread.getReadSum();
			//线程状态
			String threadStatus = readFileThread.getThreadStatus();
			if("completed".equals(threadStatus)){ //线程已经运行完毕
				ConstantMap.constantMap.remove(threadId);
				response.getOutputStream().println("success,,,"+threadId+",,,"+threadStatus+",,,"+totleSize+",,,"+readSize);
				return ;
			}else if("error".equals(threadStatus)){ //出错
				ConstantMap.constantMap.remove(threadId);
				response.getOutputStream().println("failed,,,"+threadId+",,,"+threadStatus+",,,"+totleSize+",,,"+readSize);
				return ;
			}else if("uncompleted".equals(threadStatus)){ //未完成
				response.getOutputStream().println("running,,,"+threadId+",,,"+threadStatus+",,,"+totleSize+",,,"+readSize);
				return ;
			}
			return ;
		}else{ // 一个新的请求
			File filePaht = new File("D:\\TestM\\Exam\\"+UUID.randomUUID().toString()+subfix);
			//文件夹不存在就创建
			if(!filePaht.getParentFile().exists()){
				filePaht.getParentFile().mkdirs();
			}
			FileOutputStream output = new FileOutputStream(filePaht);
			threadId = UUID.randomUUID().toString();
			
			//创建一个新的线程
			ReadFileThread readFileThread = new ReadFileThread(input, output,readSum);
			Thread thread = new Thread(readFileThread);
			thread.start();
			//获取已读大小
			long readSize = readFileThread.getReadSum();
			//线程状态
			String threadStatus = readFileThread.getThreadStatus();
			if("completed".equals(threadStatus)){ //线程已经运行完毕
				ConstantMap.constantMap.remove(threadId);
				System.out.println("end");
				response.getOutputStream().println("success,,,"+threadId+",,,"+threadStatus+",,,"+totleSize+",,,"+readSize);
				return ;
			}else if("error".equals(threadStatus)){ //出错
				ConstantMap.constantMap.remove(threadId);
				response.getOutputStream().println("failed,,,"+threadId+",,,"+threadStatus+",,,"+totleSize+",,,"+readSize);
				return ;
			}else if("uncompleted".equals(threadStatus)){ //未完成
				ConstantMap.constantMap.put(threadId, readFileThread);
				response.getOutputStream().println("running,,,"+threadId+",,,"+threadStatus+",,,"+totleSize+",,,"+readSize);
				return ;
			}
		}
		return ;
		
	}
 

 

 

class ReadFileThread implements Runnable{
		
		InputStream input;
		FileOutputStream output;
		String threadStatus = "uncompleted";
		long readSum;
		
		public String getThreadStatus() {
			return threadStatus;
		}
		public void setThreadStatus(String threadStatus) {
			this.threadStatus = threadStatus;
		}
		
		public Long getReadSum() {
			return readSum;
		}
		
		public ReadFileThread(InputStream input,FileOutputStream output, Long readSum) {
			this.input = input;
			this.output = output;
			this.readSum = readSum;
		}
		@Override
		public void run() {
			int readLength = 0;
			byte[] buffer = new byte[1444]; 
			try {
				while ( (readLength = input.read(buffer)) != -1) { 
					readSum += readLength; 
					System.out.println("已读大小:--》"+readSum);
					output.write(buffer, 0, readLength); 
				} 
			} catch (Exception e) {//出错
				this.setThreadStatus("error");
			}finally{
				try {//完成,成功
					this.setThreadStatus("completed");
					if(null != output){
						output.close();
					}
					if(null != output){
						input.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
				
			}
		}
		
	}
 

 

package com.exam.bean.common;

import java.util.Hashtable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ConstantMap {
	//此处使用 hashtable ,防止并发问题
	public static Hashtable<String, Object> constantMap = new Hashtable<>();
	
	public static void setConstantMap(String key,Object value){
		if(constantMap.containsKey(key)){
			constantMap.remove(key);
			constantMap.put(key, value);
		}else{
			constantMap.put(key, value);
		}
	}
	
	public static Object getConstantMap(String key){
		Pattern pattern = Pattern.compile("\r\n");
		Matcher matcher = pattern.matcher(key);
		key = matcher.replaceAll("");
		if(constantMap.containsKey(key)){
			return constantMap.get(key);
		}
		return null;
	}
	
	public static Object removeConstantMap(String key){
		if(constantMap.containsKey(key)){
			return constantMap.remove(key);
		}
		return null;
	}
	
	
	
	
}

 

 

 

 

 

 

 

 

运行效果如下:



 

 

 

 另外附上:juqery.form.js

 

 

 

猜你喜欢

转载自1960370817.iteye.com/blog/2400343