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