在网页中实现页面无刷新的进度条显示不是一件很麻烦的事情,但如果这个进度条要能准确反映当前事务或者复杂逻辑的执行进度,那么却并不是一件容易的事情,目前AJAX技术流行,所以本文作者试想通过AJAX来实现网页准确进度条,以銄读者。
首先应该想一个问题,复杂事务或者事务逻辑如果不按线程方式运行,运行在JAVA运行中根本无法跳过复杂事务去处理进度显示,所以我们这边很自然的想到复杂事务或者业务逻辑用多线程实现。
再想另一个问题,事务处理应该需要网页上的一系列参数信息的,那么如何获取这些参数呢,这个似乎容易想到,传一个HttpServletRequest过去就可以了。
为了进度条公用,所有的复杂事务处理都应该实现同一个接口或者抽象类,我这里用了一个接口,如下:
- public interface IprogressBar {
- public void execute(HttpServletRequest req,String pbid);//执行复杂事务
- }
- 用一个实现多线程的抽象类,如下:
- public abstract class AbstractProgressBar extends TimerTask implements IprogressBar {
- private HttpServletRequest request;
- private String pbid;
- public AbstractProgressBar(){
- }
- //子类必须重载这个函数
- public abstract void execute(HttpServletRequest req, String pbid);
- public void run() {
- execute(request,pbid);
- }
- public void setRequest(HttpServletRequest req){
- this.request=req;
- }
- public void setPbid(String pbid){
- this.pbid=pbid;
- }
- }
- 设计到具体项目不便给出代码,这里我另外写了一个测试类,也就是执行复杂事务处理的类,如下:
- public class TestPB extends AbstractProgressBar{
- public void execute(HttpServletRequest req, String pbid) {
- String sql="insert into temp_table(idx)values(?)";
- int pid=Integer.parseInt(pbid);
- ProgressBar pb=new ProgressBar(pid,300,0,1);
- //模拟大事务
- for(int i=0;i<300;i++){
- DbUtils.executeUpdate(sql,new Object[]{new Integer(i)});
- //控制进度
- pb.stepIt();
- }
- }
- }
- 接着利用AJAX技术来实现网页的无刷新进度条实现,代码如下:
- <%@ page contentType="text/html;charset=UTF-8"%>
- <title>无刷新页面进度条测试</title>
- <STYLE TYPE="text/css">
- <!--
- BODY {OVERFLOW:scroll;OVERFLOW-X:hidden}
- .DEK {POSITION:absolute;VISIBILITY:hidden;Z-INDEX:200;}
- //-->
- </STYLE>
- <script type="text/javascript">
- var xmlHttp;
- var pbid;//进度条ID
- function createXMLHttpRequest(){
- if (window.ActiveXObject) {
- xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
- }
- else if (window.XMLHttpRequest) {
- xmlHttp = new XMLHttpRequest();
- }
- }
- function checkDiv() {
- var progress_bar = document.getElementById("progressBar");
- if (progress_bar.style.visibility != "visible") {
- progress_bar.style.visibility = "visible";
- }else
- {
- progress_bar.style.visibility = "hidden";
- }
- }
- function go() {
- createXMLHttpRequest();
- checkDiv();
- var url = "../servlet/ProgressBarServlet?task=create&impcls=blogcn.pb.imp.TestPB";//其中blogcn.pb.imp.TestPB是复杂事务的实现类
- var button = document.getElementById("go");
- button.disabled = true;
- xmlHttp.open("GET", url, true);
- xmlHttp.setRequestHeader("Content-Type", "text/xml;charset=gb2312");
- xmlHttp.onreadystatechange = goCallback;
- xmlHttp.send(null);
- }
- function goCallback(){
- if (xmlHttp.readyState==4)
- {
- if (xmlHttp.status==200) {
- pbid=xmlHttp.responseXML.getElementsByTagName("pbid")[0].firstChild.data;
- setTimeout("pollServer()", 2000);
- }
- }
- }
- function pollServer() {
- createXMLHttpRequest();
- var url = "../servlet/ProgressBarServlet?task=poll&pbid="+pbid;
- xmlHttp.open("GET", url, true);
- xmlHttp.onreadystatechange = pollCallback;
- xmlHttp.send(null);
- }
- function pollCallback(){
- if (xmlHttp.readyState == 4) {
- if (xmlHttp.status == 200) {
- var percent_complete =
- xmlHttp.responseXML
- .getElementsByTagName("percent")[0].firstChild.data;
- if (percent_complete < 100) {
- PB1.pos=percent_complete;
- PB1.Update();
- setTimeout("pollServer()", 2000);
- } else {
- PB1.pos=100;
- PB1.Update();
- document.getElementById("go").disabled = false;
- }
- }
- }
- }
- <input type="button" value="执行大事务" id="go" onclick="go();"/>
- <DIV id="progressBar">
- <script language="javascript">
- var PB1=new TProgressBar("myPB1",220,180,375,20);
- PB1.Create();
- PirateCount=100;
- PID=PirateCount-2;
- PB1.Reposition();
- PB1.max=PID;
文章点评