文件下载 监控 服务执行进度

一 、进度条工具类ProgressBarThread:

public class ProgressBarThread implements Runnable{ private ArrayList proList = new ArrayList(); 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"%> <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"> <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> <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.attr('id','form'); form.attr('style', 'display:none'); //在form表单中添加查询参数 form.attr('target', ''); form.attr('method', 'post'); form.attr('action', fromAction+''); var input1 = $(''); 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>

实现思路:

  1. 首先前台搭建好下载页面,绘制一个进度条
  2. 后台写好文件下载功能
  3. 在前台中使用一个隐藏的表单,用来执行下载功能,用JS提交表单实现下载,这样执行下载时不会跳转页面
  4. 在后台实现文件下载时检测文件下载进度,同时用进度工具类来存储下载进度
  5. 在Controller中定义一个进度工具类全局引用变量,但不需要初始化,当用户进行下载时初始化进度工具类全局引用变量,已达到一个用户下载对用一个进度
  6. 前台写入Ajax事件,用JS的定时函数,来调用Ajax事件,一秒访问一次后台的进度工具类的全局引用变量,用来获取下载进度
  7. 当Ajax获取的下载进度为100%时,调用JS的停止定时函数,结束前台文件下载进度的检测
  8. 文件下载结束

JS中用到的两个函数:

    1. setInterval(function,time);第一个参数为要执行的方法,第二个参数为每隔多少时间执行一次,此函数有返回值,当调用停止定时函数时,需要传入此setInterval()方法的返回值,来结束此函数 
      例如:var int = setInterval(…. , …);

    2. clearInterval(obj);方法参数为setInterval()方法的返回值,用来结束定时函数 
      例如:var int = setInterval(…. , …); 
      clearInterval(int);

 

转载于:https://www.cnblogs.com/XFJ-XXX/p/9240124.html

你可能感兴趣的:(javascript,前端,java)