此案例使用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