导航

AJAX 和 JSP 10.5(转)实现进度条【转】

Posted on 2011-08-25 20:05  菜鸟都不容易  阅读(1129)  评论(0编辑  收藏  举报

1.服务器端代码

服务器端代码主要实现依据客户端的请求信息,返回相应百分比数字。打开记事本,输入下列代码:

案例10-5

<%@ page contentType="text/html; charset=gb2312" language="java" import="java.sql.*" errorPage="" %>

<%!

int counter = 1;//注意:多用户将共享此变量,此进度条只适合单用户

%>

<%

String task = request.getParameter("task");

        String res = "";

        

        if (task.equals("create")) {

            res = "1";

            counter = 1;

        }

        else {

            String percent = "";

            switch (counter) {

                case 1: percent = "10"; break;

                case 2: percent = "23"; break;

                case 3: percent = "35"; break;

                case 4: percent = "51"; break;

                case 5: percent = "64"; break;

                case 6: percent = "73"; break;

                case 7: percent = "89"; break;

                 case 8: percent = "100"; break;

            }

            counter++;

               

            res = "<percent>" + percent + "</percent>";

        }

        response.setContentType("text/xml");

        response.setHeader("Cache-Control", "no-cache");

        out.println("<response>");

        out.println(res);

        out.println("</response>");

        out.close();   

%>

将上述代码保存,名称为ProgressBarJsp.jsp。在该文件中,声明了一个变量counter,并赋值为1,该变 量是进度条返回百分比数字的依据。在下面使用request对象获取客户端传送的变量task的值,如果该值为“create”,表示需要重新创建进度 条,并设定counter的值为1。如果task不是create,则会依据counter的值返回百分比数字,完成一次操作,counter值加1。

2.客户端代码

本案例的客户端代码主要实现依据返回百分比数字显示进度条的状态。打开记事本,输入下列代码:

案例10-5

<html>

<head>

    <title>JSP+Ajax 进度条</title>

    <script type="text/javascript">

        var xmlHttp;

        var bar_color = 'blue';

        var span_id = "yellow";

        var clear = "&nbsp;&nbsp;&nbsp;"

        function createXMLHttpRequest() {

            if (window.ActiveXObject) {

                xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");

            }

            else if (window.XMLHttpRequest) {

                xmlHttp = new XMLHttpRequest();               

            }

        }

        function go() {

            createXMLHttpRequest();

            checkDiv();

            var url = "ProgressBarJsp.jsp?task=create";

            xmlHttp.open("GET", url, true);

            xmlHttp.onreadystatechange = goCallback;

            xmlHttp.send(null);

        }

        function goCallback() {

            if (xmlHttp.readyState == 4) {

                if (xmlHttp.status == 200) {

                    setTimeout("pollServer()", 2000);

                }

            }

        }

      

function pollServer() {

            createXMLHttpRequest();

            var url = "ProgressBarJsp.jsp?task=poll";

            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;

                    var index = processResult(percent_complete);

                    for (var i = 1; i <= index; i++) {

                        var elem = document.getElementById("block" + i);

                        elem.innerHTML = clear;

                        elem.style.backgroundColor = bar_color;

                        var next_cell = i + 1;

                        if (next_cell > index && next_cell <= 9) {

               document.getElementById("block" + next_cell).innerHTML = percent_complete + "%";

                        }

                    }

                    if (index < 9) {

                        setTimeout("pollServer()", 2000);

                    } else {

                        document.getElementById("complete").innerHTML = "网站已完成加载!";

                    }

                }

            }

        }

        function processResult(percent_complete) {

            var ind;

            if (percent_complete.length == 1) {

                ind = 1;

            } else if (percent_complete.length == 2) {

                ind = percent_complete.substring(0, 1);

            } else {

                ind = 9;

            }

            return ind;

        }

function checkDiv() {

            var progress_bar = document.getElementById("progressBar");

            if (progress_bar.style.visibility == "visible") {

                clearBar();

                document.getElementById("complete").innerHTML = "";

             } else {

                progress_bar.style.visibility = "visible"

            }

        }

function clearBar() {

            for (var i = 1; i < 10; i++) {

                var elem = document.getElementById("block" + i);

                elem.innerHTML = clear;

                elem.style.backgroundColor = "white";

            }

        }

    </script>

</head>

<body onload="go();">

    <h1 align=center>网站正在加载中,请稍候</h1>

    <p>

    <table align="center">

        <tbody>

            <tr><td>

                 <div id="progressBar" style="padding:2px;border:solid yellow 2px;visibility:hidden">

                    <span id="block1">&nbsp;&nbsp;&nbsp;</span>

                    <span id="block2">&nbsp;&nbsp;&nbsp;</span>

                    <span id="block3">&nbsp;&nbsp;&nbsp;</span>

                    <span id="block4">&nbsp;&nbsp;&nbsp;</span>

                    <span id="block5">&nbsp;&nbsp;&nbsp;</span>

                    <span id="block6">&nbsp;&nbsp;&nbsp;</span>

                    <span id="block7">&nbsp;&nbsp;&nbsp;</span>

                    <span id="block8">&nbsp;&nbsp;&nbsp;</span>

                    <span id="block9">&nbsp;&nbsp;&nbsp;</span>

                </div>

            </td></tr>

            <tr><td align="center" id="complete"></td></tr>

        </tbody>

    </table>

</body>

</html>

将上述代码保存,名称为JspprogressBar.html。在该文件中,JavaScript函数createXMLHttpRequest()主 要用来创建XMLHttpRequest对象,go()函数完成向服务器端发送异步请求,该函数在网页加载时被调用,其主要作用就是通知服务器端,并在客 户端开始运行进度条。goCallback()函数主要处理服务器端响应,并每隔2秒调用函数pollServer()函数。pollServer()函 数也是向服务器端发送异步请求,主要请求服务器端响应的百分比数字。pollCallback()函数主要处理服务器端响应,即依据服务器端的返回数字, 指定进度条的显示状态。这里需要注意的是,goCallback()函数只执行一次,而pollCallback()函数可以执行多次。其余的三个函数都 是实现进度条的辅助函数。
将上述两个JSP文件复制到JSP目录下。打开IE浏览器,在地址栏中输入http://localhost:8080/JSP/JspprogressBar.html

------------------------以下是从跳转action的实例--------------

在一个项目中,需要在后台把某个目录下的文件信息写入数据库(初始化文件)。当文件数量太多时,等待时间较长。因此需用ajax技术做一个显示处理进度的进度条。
 
进度条显示页面before_initiallize.jsp:

  <script type="text/javascript">
        var xmlHttp;
        //var key;
        var startSeconds = new Date().getSeconds();//
        //ajax第一步:创建XMLHttpRequest
        function createXMLHttpRequest(){
            if (window.ActiveXObject){
                xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
            else if (window.XMLHttpRequest){
                xmlHttp = new XMLHttpRequest();               
            }
        }
  //首先执行的函数:准备ajax交互
        function go(){
            createXMLHttpRequest();
            clearBar();
            var url = "actObjInfoAction.do?method=initiallize&task=create";//要用不同的参数来控制后台的处理
            //var button = document.getElementByIdx("go");
            //button.disabled = true;
            xmlHttp.open("GET", url, true);
            xmlHttp.onreadystatechange = goCallback;//当状态改变时调用的函数:goCallBack
            xmlHttp.send(null);
        }
  //向服务端发送create参数后,被指定用来处理onreadystatechange事件的函数
        function goCallback(){
            if (xmlHttp.readyState == 4) {
                if (xmlHttp.status == 200) {
                    //setTimeout("pollServer()", 0);//为pollServer函数设置延时:2000毫秒
     pollServer();
                }
            }
        }
        //与服务端交互:
        function pollServer() {
            createXMLHttpRequest();
            var url = "actObjInfoAction.do?method=initiallize&task=poll";//要用不同的参数来控制后台的处理
            xmlHttp.open("GET", url, true);
            xmlHttp.onreadystatechange = pollCallback;
            xmlHttp.send(null);
        }
        //与服务端交互开始后,被指定用来处理onreadystatechange事件的函数
        function pollCallback() {
            if (xmlHttp.readyState == 4) {
                if (xmlHttp.status == 200) {
                    var percent_complete = xmlHttp.responseXML.getElementsByTagName_r("percent")[0].firstChild.data;

                    var progress = document.getElementByIdx("progress");
                    var progressPersent = document.getElementByIdx("progressPersent");
     progress.width = percent_complete + "%";
     progressPersent.innerHTML = percent_complete + "%";
                    if (percent_complete < 100) {
                        //setTimeout("pollServer()", 0);//2000
      pollServer();
                    } else {
                     var endSeconds = new Date().getSeconds();//
                     var during = endSeconds - startSeconds;
                        document.getElementByIdx("complete").innerHTML = "初始化完成!花费 ";
                        document.getElementByIdx("complete").innerHTML += during;
                        document.getElementByIdx("complete").innerHTML += " 秒";
                        
                        //document.getElementByIdx("go").disabled = false;
                    }
                }
            }
        }
  //一开始显示文字提示:
 function clearBar() {
   var progress_bar = document.getElementByIdx("progressBar");
   var progressPersent = document.getElementByIdx("progressPersent");
   var complete = document.getElementByIdx("complete");
   progress_bar.style.visibility = "visible"
   progressPersent.innerHTML = " ";
   complete.innerHTML = "正在初始化,请稍等...";
 }
    </script>

 </head>
 <LINK href="include/css/windows.css" type=text/css rel=stylesheet>
 <link href="include/css/futuretable.css" type="text/css" rel="stylesheet">

 <body class="contentbodymargin" onLoad="go()">
  <div id="contentborder">
   <div id="progressBar" style="padding:0px;border:solid black 0px; visibility:hidden">
    <table width="300" border="0" cellspacing="0" cellpadding="0" align="center">
     <tr>
      <td align="center" id="progressPersent"></td>
     </tr>
     <tr>
      <td>
       <table width="100%" border="1" cellspacing="0" cellpadding="0" bordercolor="#000000">
        <tr>
         <td>
          <table width="0%" border="0" cellspacing="0" cellpadding="0" id="progress">
           <tr bgcolor="#0099FF"><td></td></tr>
          </table>
         </td>
        </tr>
       </table>
      </td>
     </tr>
     <tr>
      <td align="center" id="complete">
       完成
      </td>
     </tr>
    </table>
   </div>
<!--input id = "go" name="run" type="button" value="run" onClick="go();"-->
  </div>
  
 </body>

 后台处理java文件:

 public ActionForward initiallize(ActionMapping mapping,
   ActionForm actionForm, HttpServletRequest request,
   HttpServletResponse response) {
  ActObjManager aom = (ActObjManager) getBean("actObjManager");
  String rootPath = request.getRealPath("dirfiles");
  File baseDir = new File(rootPath);
  List files = FileOperate.getSubFiles(baseDir);// 得到目录中包括的所有文件(不包括空目录)
  
  // ajax进度条相关:
  String task = request.getParameter("task");
  String res = "0";
  int totalFileNum = files.size();// 需初始化的总共文件数,可用来做前期的准备工作

  if (task.equals("create"))//这个if块内只执行一次
  {
   res = "1";
   counter = 1;//不清楚这个语句的作用。但这里写成0的话页面会报JS错误
   
   // 首先删除actobj中所有记录:
   List actobjs = aom.getActObjs();
   for (int i = 0; i < actobjs.size(); i++) {
    ActObj actobj = (ActObj) actobjs.get(i);
    aom.delActObj(actobj.getObjid());
   }
  }
  else//主要的处理写在这个else块内。注意:不要循环,因为这个块会被多次调用
  {
   String percent = "";
   //开始初始化文件:
   if ( counter < totalFileNum )//开始初始化文件。防止下标越界
    initiallizeFile(request,response,files,counter-1);//初始化文件的函数。因为counter是从1开始,所以这里要-1
   
   percent = String.valueOf((int) (counter * 100) / totalFileNum);
   counter++;
   res = "" + percent + "";
  }
  try {
   PrintWriter out = response.getWriter();
   response.setContentType("text/xml");
   response.setHeader("Cache-Control", "no-cache");
   out.println("");
   out.println(res);
   out.println("");
   out.close();
  } catch (Exception e) {
   e.printStackTrace();
  }
  return null;

 }