这个例子是《Ajax基础教程》上面的,我自己稍微做了点修改。利用xmlHttpRequest对象不断刷新页面上指定位置的内容,但不用刷新整个页面。点击"Launch"开始自动更新,更新完毕显示"Done!",然后可以点击"Clear"清除更新的内容,或者再次点击"Launch"开始下一次更新。
dynamicUpdate.jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!
DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><
html><
head><
meta. http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><
title>Dynamic Update Test</title><
script> var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); function doStart() { document.getElementById("go").disabled = true;document.getElementById(
"clear").disabled = true; var url = "DynamicUpdateServlet?task=reset";xmlHttp.open(
"GET", url, true);xmlHttp.onreadystatechange = startCallback;
xmlHttp.send(
null); }function
startCallback() {if
(xmlHttp.readyState == 4) {if
(xmlHttp.status == 200) { setTimeout("pollServer()", 2000);refreshTime();
}}
}
function
refreshTime() {var
time_span = document.getElementById("time"); var time_val = time_span.innerHTML; var new_int_val = time_val * 1 - 1; if (new_int_val > -1) { setTimeout("refreshTime()", 1000);time_span.innerHTML = new_int_val;
} else { time_span.innerHTML = 2; }}
function
pollServer() {var
url = "DynamicUpdateServlet?task=foo";xmlHttp.open(
"GET", url, true);xmlHttp.onreadystatechange = pollCallback;
xmlHttp.send(
null); }function
pollCallback() {if
(xmlHttp.readyState == 4) {if
(xmlHttp.status == 200) {var
message = xmlHttp.responseXML.getElementsByTagName("message")[0].firstChild.data; var new_row = createRow(message); var table = document.getElementById("dynamicUpdateArea"); var table_body = table.getElementsByTagName("tbody").item(0); var first_row = table_body.getElementsByTagName("tr").item(1);table_body.insertBefore(new_row, first_row);
if (message != "Done!") { setTimeout("pollServer()", 2000);refreshTime();
} else { document.getElementById("go").disabled = false;document.getElementById(
"clear").disabled = false; }}
}
}
function
createRow(message) {var
row = document.createElement("tr"); var cell = document.createElement("td"); var cell_data = document.createTextNode(message);cell.appendChild(cell_data);
row.appendChild(cell);
return row; }function
clearRows() {var
rows = document.getElementsByTagName("tbody")[0].childNodes; var container = document.getElementsByTagName("tbody").item(0); while(container.hasChildNodes()) { container.removeChild(rows[1]); }}
</
script></
head><
body><
h1>Ajax Dynamic Update Example</h1><br/>The page will automatically update itself:
<
input type="button" value="Launch" id="go" onclick="doStart();" /><
input type="button" value="Clear" id="clear" onclick="clearRows();" /><br/>Page will refresh in
<span id="time"> 2 </span> seconds.<br/><
table id="dynamicUpdateArea" align="left" > <tbody> <tr id="row0"> <td></td> </tr> </tbody></
table><br/></
body></
html> DynamicUpdateServlet.java:
package src;
import
java.io.IOException;import
java.io.PrintWriter;import
javax.servlet.ServletException;import
javax.servlet.http.HttpServletRequest;import
javax.servlet.http.HttpServletResponse; public class DynamicUpdateServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet { private int counter = 1; public DynamicUpdateServlet() { super();}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/xml");response.setHeader(
"Cache-Control", "no-cache");String res=
"";String task = request.getParameter(
"task");String message =
"Start"; if (task.equals("reset")) { counter = 1;}
else { switch (counter) { case 1: message = "This is case 1"; break; case 2: message = "This is case 2"; break; case 3: message = "This is case 3"; break; case 4: message = "This is case 4"; break; case 5: message = "This is case 5"; break; case 6: message = "Done!"; break;}
counter++;}
res =
"<message>" + message + "</message>";PrintWriter ut = response.getWriter();
out.println(
"<response>");out.println(res);
out.println(
"</response>");out.close();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response);}
}
我们先来看dynamicUpdate.jsp里面的内容。点击"Launch"后,触发doStart()。首先把两个按钮屏蔽掉,然后将task=reset传给处理的servlet即DynamicUpdateServlet,并设置请求状态改变后,由startCallback函数处理。当send方法调用后,task参数以GET方法被传给DynamicUpdateServlet。在这个Servlet里面,有一个变量为counter,以后更新用的。里面的if语句先判断出task=reset,然后执行counter=1。虽然这里也写了<response>这些xml文件的内容,不过现在还没有用。那么,回到了第一个页面,由startCallback函数来处理。在这个函数里面,开始每隔2秒钟调用pollServer函数,并刷新计时器。
在pollServer函数里面,将task参数设置为foo(其实只要不设置为reset就可以),同时以GET方法传给DynamicUpdateServlet,之后由pollCallback函数处理。send方法被调用后,来看servlet。这个时候,task已经不是reset了,所以执行switch语句,此时counter=1,所以message="This is case 1"。然后在out.println里面写一个xml文件。接着就是重点的pollCallback函数了。
在这个函数里,请求处理完成后,首先通过xmlHttp.responseXML得到message内容,然后调用createRow函数来创建每一条被更新的内容,这些内容被放在<tr><td>标记里面。然后,得到该页面中显示动态更新的位置,这里是id为"dynamicUpdateArea"的table。然后查找到<tbody>中的<tr>,把每一条被更新的内容放到现有的<tr>前面一个位置。接着判断message的内容,如果message不为"Done!",则继续调用pollServer并刷新时间;否则结束更新,并恢复两个按钮。
当点击"Clear"按钮后,clearRows函数会先找到<tbody>的所有子节点,如果还有子节点就逐一去掉,以此来清除已经显示出来的内容。
这里面,更新的内容是一个简单的模拟。我想,实际应用中可以通过查找数据库来写入更新的内容。这个以后有待研究。
注意!有可能从这篇文章直接copy后执行会报错,因为博客输入可能会出现问题。只要稍微作修改即可,问题应该不是太大,应该能看懂并知道如何修改。例如,servlet中,PrintWriter ut其实是PrintWriter out。