文件下载 监控 服务执行进度
Posted xfj-xxx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文件下载 监控 服务执行进度相关的知识,希望对你有一定的参考价值。
一 、进度条工具类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);
以上是关于文件下载 监控 服务执行进度的主要内容,如果未能解决你的问题,请参考以下文章