文件下載 監控 服務執行進度

一 、進度條工具類ProgressBarThread:javascript

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後臺2、
 
@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前端:3、

<%@ 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>

實現思路:css

  1. 首先前臺搭建好下載頁面,繪製一個進度條
  2. 後臺寫好文件下載功能
  3. 在前臺中使用一個隱藏的表單,用來執行下載功能,用JS提交表單實現下載,這樣執行下載時不會跳轉頁面
  4. 在後臺實現文件下載時檢測文件下載進度,同時用進度工具類來存儲下載進度
  5. 在Controller中定義一個進度工具類全局引用變量,但不須要初始化,當用戶進行下載時初始化進度工具類全局引用變量,已達到一個用戶下載對用一個進度
  6. 前臺寫入Ajax事件,用JS的定時函數,來調用Ajax事件,一秒訪問一次後臺的進度工具類的全局引用變量,用來獲取下載進度
  7. 當Ajax獲取的下載進度爲100%時,調用JS的中止定時函數,結束前臺文件下載進度的檢測
  8. 文件下載結束

JS中用到的兩個函數:html

    1. setInterval(function,time);第一個參數爲要執行的方法,第二個參數爲每隔多少時間執行一次,此函數有返回值,當調用中止定時函數時,須要傳入此setInterval()方法的返回值,來結束此函數 
      例如:var int = setInterval(…. , …);前端

    2. clearInterval(obj);方法參數爲setInterval()方法的返回值,用來結束定時函數 
      例如:var int = setInterval(…. , …); 
      clearInterval(int);java

相關文章
相關標籤/搜索