在网页中实现页面无刷新的进度条显示不是一件很麻烦的事情,但如果这个进度条要能准确反映当前事务或者复杂逻辑的执行进度,那么却并不是一件容易的事情,目前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; |