最近做Java web项目, 遇到了struts的Action中有很耗时的计算保存任务,就想做一个进度条显示。看了别人的进度条实现,自己也照着做了一下。
- 先写一个类ProgressSingleton 专门用于保存进度,其中静态变量Hashtable中<key, value>对,key为进度唯一标记,value为进度的值。
import java.util.Hashtable;
public class ProgressSingleton {
private static Hashtable<Object, Object> table = new Hashtable<>();
public static void put(Object key, Object value) {
table.put(key, value);
}
public static Object get(Object key) {
return table.get(key);
}
public static Object remove(Object key) {
return table.remove(key);
}
}
- 测试的Action类
import org.apache.struts2.ServletActionContext;
import cn.uestc.core.action.BaseAction;
/**测试类*/
public class WaitAction extends BaseAction {
private int progress;//用于前端获取进度
/** 1.执行主耗时任务 */
public String taskTest() throws Exception {
int percent = 0;//初始化进度
String sessionID = ServletActionContext.getRequest().getSession().getId();//用sessionID做本次进度显示标志
for (int i = 0; i <= 100; i++) {//这里需要根据实际情况计算进度值,这里直接用循环模拟0-100进度了
ProgressSingleton.put(sessionID, percent);
percent++;
Thread.sleep(200);//模拟耗时任务
}
//ProgressSingleton.remove(sessionID); //目前不知道为什么这句话加上会报错
return "taskTest";
}
/** 2.获取主任务执行进度 */
public String getStatus() {
String sessionID = ServletActionContext.getRequest().getSession().getId();//获取sessionID
progress = (int) ProgressSingleton.get(sessionID);//设置进度
return "getStatus";
}
/**跳转进度条*/
public String show() {
return "show";
}
public void setProgress(int progress) {
this.progress = progress;
}
public int getProgress() {
return progress;
}
}
3.配置wait-struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="hello-progress" namespace="/progress" extends="json-default">
<action name="wait_*" class="cn.uestc.test.wait.action.WaitAction" method="{1}">
<result name="{1}">/WEB-INF/jsp/test/{1}.jsp</result>
<result name="show">/WEB-INF/jsp/test/progress.jsp</result>
<result name="taskTest" type="json" />
<result name="getStatus" type="json" />
</action>
</package>
</struts>
4.前端页面与jquery ajax实现
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>进度显示</title>
<%@include file="/common/header.jsp"%> <!-- header.jsp中引入的jquery,下面的被注释掉 -->
<%-- <script type="text/javascript" src="${basePath}js/jquery/jquery-1.10.2.min.js"></script> --%>
<style type="text/css">
.outer {/*进度条外框,用于显示总长度*/
display: inline-block;
width: 200px;
height: 20px;
line-height: 20px;
background: #EEE;
}
.inner {/*进度条内框,用于显示当前实时进度*/
display: inline-block;
height: 20px;
line-height: 20px;
width: 0px;
background: green;
}
#percent {/*用于显示进度百分比*/
display: inline-block;
width: 50px;
height: 20px;
color: yellow;
}
</style>
<script type="text/javascript">
$(function(){
$('#btn1').click(function(event) {
//阻止默认事件
event.preventDefault();
//循环查看状态
var t = setInterval(function(){
$.ajax({
url: 'progress/wait_getStatus.action',
type: 'POST',
dataType: 'json',
success: function (resp) {
console.log("返回结果"+resp.progress);
$('#percent').html(resp.progress+"%");
$('.inner').width(resp.progress*2);
},
error: function(){
console.log("error");
}
});
}, 100);
//上传文件
$.ajax({
url: 'progress/wait_taskTest.action',
type: 'POST',
dataType: 'json',
success: function (responseText) {
//上传完成,清除循环事件
console.log("############clear clear clear");
clearInterval(t);
//将进度更新至100%
$('#percent').html(100 + "%");
$('.inner').width(100*2);
},
error: function(){
console.log("error");
}
});
return false;
});
})
</script>
</head>
<body>
<br/><br/>
<input type="button" id="btn1" value="点击开始" />
<br/><br/>
<!-- 下面是进度条 -->
<span class="outer">
<span class="inner"><span id="percent"></span></span>
</span>
</body>
</html>
最终效果图: