文件下載 監控 服務執行進度
阿新 • • 發佈:2018-06-28
bmi In sub lis attribute 復制 讀取 jquary decimal
一 、進度條工具類ProgressBarThread:
public class ProgressBarThread implements Runnable{
private ArrayList<Integer> proList = new ArrayList<Integer>();
private int progress;//當前進度
private int totalSize;//總大小
private boolean run = true;
private java.text.DecimalFormat df =
new java.text.DecimalFormat("#.00");//格式化數字
//進度(百分比)
private String sum ;
public ProgressBarThread(int totalSize){
this.totalSize = totalSize;
//創建進度條
}
//獲取總進度(百分比)
public String total(){
return sum;
}
/**
* @param progress 進度
*/
public void updateProgress(int progress){
synchronized (this.proList) {
if(this.run){
this.proList.add(progress);
this.proList.notify();
}
}
}
public void finish(){
this.run = false;
//關閉進度條
}
@Override
public void run() {
synchronized (this.proList) {
try {
while (this.run) {
if(this.proList.size()==0){
this.proList.wait();
}
synchronized (proList) {
this.progress += this.proList.remove(0);
//更新進度條
sum = df.format((int)(((float)this.progress/this.totalSize)*100));
sum = sum.substring(0, sum.indexOf("."));
System.out.println("當前進度:"+sum+"%");
}
}
System.err.println("下載完成");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
二、
Controller後臺
@Controller
@RequestMapping("download")
public class DownloadController {
//創建進度條
//必須要定義為全局變量,這樣前臺才能訪問進度,且一個用戶一個進度
private ProgressBarThread pbt;
/**
* @Description: 獲取進度
* @param: @param request
* @param: @param response
* @return void
* @throws
*/
@RequestMapping("total")
public void text1(HttpServletRequest request , HttpServletResponse response){
//設置輸出文本格式
response.setContentType("application/json;charset=utf-8");
//獲取進度
String total = pbt.total();
//創建JSON
JSONObject json = new JSONObject();
//存儲進度
json.put("total", total);
try {
//向前臺返回進度
response.getWriter().write(json.toJSONString());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* @Description: 跳轉至下載頁面
* @throws
*/
@RequestMapping("text")
public String text(HttpServletRequest request){
return "text/text";
}
/**
* @Description: 文件下載
* @param: @param fileName 文件名稱
* @return String 返回值為null
* @throws
*/
@RequestMapping(value = "download")
public void download(String fileName, HttpServletRequest request,
HttpServletResponse response) {
response.setCharacterEncoding("utf-8");
response.setContentType("multipart/form-data");
response.setHeader("Content-Disposition", "attachment;fileName="
+ fileName);
try {
// /WEB-INF/download文件夾的根目錄
String path = request.getSession().
getServletContext().getRealPath("/WEB-INF/download");
// 獲取相應文件的流
// File.separator(Windows系統為‘/‘)
File file = new File(path + File.separator + fileName);
//創建進度條
pbt = new ProgressBarThread((int)file.length());
//開啟線程,刷新進度條
new Thread(pbt).start();
//設置文件長度
response.setHeader("Content-Length", (int)file.length()+"");
//IO流復制
InputStream inputStream = new FileInputStream(file);
OutputStream os = response.getOutputStream();
byte[] b = new byte[2048];
int length;
while ((length = inputStream.read(b)) > 0) {
os.write(b, 0, length);
//寫完一次,更新進度條
pbt.updateProgress(length);
}
//文件讀取完成,關閉進度條
pbt.finish();
// 釋放資源
os.close();
inputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
三、
JSP前端:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>文件下載</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<!-- 引入三個讀取CSS框架 -->
<link href="http://libs.baidu.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script src="http://libs.baidu.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
<!-- 引入jQuery -->
<script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery-2.1.4.js"></script>
<script type="text/javascript">
window.onload = function (){
document.getElementById("load").onclick = function (){
//調用JS封裝的方法,實現文件下載
downLoad(‘${pageContext.request.contextPath }/download/download‘,‘myeclipse.exe‘);
//定時訪問進度
var int = setInterval(function(){
$.ajax({
type : ‘POST‘,
//訪問此url,用來返回進度
url : ‘${pageContext.request.contextPath }/download/total‘,
success:function(data){
var total = data.total;
if(total==‘100‘){
//設置下載進度
$(‘#proBar‘).css(‘width‘,‘100%‘);
alert("下載完成");
//結束當前定時任務,
//clearInterval(int)方法的參數為setInterval的變量名
//var int = setInterval...
clearInterval(int);
}else{
//設置下載進度
$(‘#proBar‘).css(‘width‘,total+‘%‘);
//alert(total);
}
}
});
//100毫秒調用一次
},100);
}
}
/*
JS實現文件下載:
利用jQuary繪制一個隱藏表單
表單裏只有一個hidden隱藏域,域的value為文件名
繪制完畢後自動提交,訪問後臺Controller,實現文件下載
參數:
fromAction:要提交的URL路徑
fileName:要下載的文件名稱
例如:fromAction:‘${pageContext.request.contextPath }/download/download‘
fileName :‘jQuery.txt‘
*/
function downLoad(fromAction,fileName) {
var form = $("<form>"); //定義一個form表單
form.attr(‘id‘,‘form‘);
form.attr(‘style‘, ‘display:none‘); //在form表單中添加查詢參數
form.attr(‘target‘, ‘‘);
form.attr(‘method‘, ‘post‘);
form.attr(‘action‘, fromAction+‘‘);
var input1 = $(‘<input>‘);
input1.attr(‘type‘, ‘hidden‘);
input1.attr(‘name‘, ‘fileName‘);
input1.attr(‘value‘, fileName+‘‘);
//將內置表單添加在頁面中
$(‘body‘).append(form);
//將隱藏域添加到表單上
form.append(input1);
form.submit();
}
</script>
</head>
<body>
<br/>
<input type="button" value="文件下載" id="load" style="position: relative;left:500px;"/>
<br/><br/>
<div class="progress" style="width: 300;position: relative;left:500px;">
<div class="progress-bar" role="progressbar" aria-valuenow="60"
aria-valuemin="0" aria-valuemax="100" style="width: 0%;" id="proBar">
<span class="sr-only">40% 完成</span>
</div>
</div>
</body>
</html>
實現思路:
- 首先前臺搭建好下載頁面,繪制一個進度條
- 後臺寫好文件下載功能
- 在前臺中使用一個隱藏的表單,用來執行下載功能,用JS提交表單實現下載,這樣執行下載時不會跳轉頁面
- 在後臺實現文件下載時檢測文件下載進度,同時用進度工具類來存儲下載進度
- 在Controller中定義一個進度工具類全局引用變量,但不需要初始化,當用戶進行下載時初始化進度工具類全局引用變量,已達到一個用戶下載對用一個進度
- 前臺寫入Ajax事件,用JS的定時函數,來調用Ajax事件,一秒訪問一次後臺的進度工具類的全局引用變量,用來獲取下載進度
- 當Ajax獲取的下載進度為100%時,調用JS的停止定時函數,結束前臺文件下載進度的檢測
- 文件下載結束
JS中用到的兩個函數:
-
setInterval(function,time);第一個參數為要執行的方法,第二個參數為每隔多少時間執行一次,此函數有返回值,當調用停止定時函數時,需要傳入此setInterval()方法的返回值,來結束此函數
例如:var int = setInterval(…. , …); -
clearInterval(obj);方法參數為setInterval()方法的返回值,用來結束定時函數
例如:var int = setInterval(…. , …);
clearInterval(int);
文件下載 監控 服務執行進度