前提条件:所有客户端都不支持 XMLHttpRequest 之类的异步查询。
1. 幌子页面,用于告诉用户目前正在执行查询
2. IFRAME 里面的轮询页面,用于执行真正的耗时查询
3. 结果呈现页面
4. 错误提示页面
5. 查询线程类
1. 幌子页面,用于告诉用户目前正在执行查询
<%@ page language="java" import="java.util.*" pageEncoding="gbk"%>
<html>
<head>
<title>幌子页面</title>
</head>
<body>
Searching, please wait a moment <br>
<IFRAME height="0" width="0" src="inner.jsp"></IFRAME>
</body>
</html>
<html>
<head>
<title>幌子页面</title>
</head>
<body>
Searching, please wait a moment <br>
<IFRAME height="0" width="0" src="inner.jsp"></IFRAME>
</body>
</html>
2. IFRAME 里面的轮询页面,用于执行真正的耗时查询
<%@ page language="java" import="java.util.*" pageEncoding="gbk"%>
<%@ page import="org.stephencat.thread.*" %>
<%
// 第二次刷新本页面时,尝试从 session 中提取已经创建的查询线程对象
QueryThread query = (QueryThread)session.getAttribute("QueryThread");
// 第一次进入本页面时,创见查询线程并启动该线程 (自动调用 run() 方法)
if(query == null){
query = new QueryThread();
Thread thread = new Thread(query);
thread.start();
}
// 轮询次数
int waits = 1;
// 执行轮询
while (waits-- > 0) {
// 出现异常或者获得结果,就结束轮询。
if (query.getException() != null || query.getResult() != null) {
break;
}
// JSP 当前线程休眠 1 秒,以等待查询线程执行查询
Thread.sleep(1000);
}
// 本次轮询结束,无论查不查得到,都把查询线程对象保存到 session 中
session.setAttribute("QueryThread", query);
// 对出现异常的页面呈现处理:转到错误页面并终止本页。注意,查询线程使用 session 传递到错误页面。
if( query.getException() !=null ){
%>
<script language="javascript">
window.parent.location.href="error.jsp";
</script>
<%
return;
}
// 未获得结果的页面呈现处理:每隔 3 秒刷新一次本页面,从而执行轮询。
if( query.getResult() == null ) {
%>
<html>
<head>
<meta http-equiv="REFRESH" content="3; URL=inner.jsp">
</head>
</html>
<%
return;
}else{ // 获得结果的页面呈现处理:转到结果呈现页面。注意:查询线程使用 session 传递到结果呈现页面。
%>
<script language="javascript">
window.parent.location.href="list.jsp";
</script>
<%
return;
}
%>
<%@ page import="org.stephencat.thread.*" %>
<%
// 第二次刷新本页面时,尝试从 session 中提取已经创建的查询线程对象
QueryThread query = (QueryThread)session.getAttribute("QueryThread");
// 第一次进入本页面时,创见查询线程并启动该线程 (自动调用 run() 方法)
if(query == null){
query = new QueryThread();
Thread thread = new Thread(query);
thread.start();
}
// 轮询次数
int waits = 1;
// 执行轮询
while (waits-- > 0) {
// 出现异常或者获得结果,就结束轮询。
if (query.getException() != null || query.getResult() != null) {
break;
}
// JSP 当前线程休眠 1 秒,以等待查询线程执行查询
Thread.sleep(1000);
}
// 本次轮询结束,无论查不查得到,都把查询线程对象保存到 session 中
session.setAttribute("QueryThread", query);
// 对出现异常的页面呈现处理:转到错误页面并终止本页。注意,查询线程使用 session 传递到错误页面。
if( query.getException() !=null ){
%>
<script language="javascript">
window.parent.location.href="error.jsp";
</script>
<%
return;
}
// 未获得结果的页面呈现处理:每隔 3 秒刷新一次本页面,从而执行轮询。
if( query.getResult() == null ) {
%>
<html>
<head>
<meta http-equiv="REFRESH" content="3; URL=inner.jsp">
</head>
</html>
<%
return;
}else{ // 获得结果的页面呈现处理:转到结果呈现页面。注意:查询线程使用 session 传递到结果呈现页面。
%>
<script language="javascript">
window.parent.location.href="list.jsp";
</script>
<%
return;
}
%>
3. 结果呈现页面
<%@ page language="java" import="java.util.*" pageEncoding="gbk"%>
<%@ page import="org.stephencat.thread.*" %>
<%
// 呈现结果
QueryThread query = (QueryThread)session.getAttribute("QueryThread");
if(query!=null){
out.println(query.getResult());
}else{
out.println("error: query instance is null!");
}
%>
<%@ page import="org.stephencat.thread.*" %>
<%
// 呈现结果
QueryThread query = (QueryThread)session.getAttribute("QueryThread");
if(query!=null){
out.println(query.getResult());
}else{
out.println("error: query instance is null!");
}
%>
4. 错误提示页面
<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<%@ page import="org.stephencat.thread.*" %>
Error occured when getting flights:<br><br>
<%
// 提示查询错误
QueryThread query = (QueryThread)session.getAttribute("QueryThread");
if(query!=null){
out.println(query.getException().getMessage());
}else{
out.println("error: query instance is null!");
}
%>
<%@ page import="org.stephencat.thread.*" %>
Error occured when getting flights:<br><br>
<%
// 提示查询错误
QueryThread query = (QueryThread)session.getAttribute("QueryThread");
if(query!=null){
out.println(query.getException().getMessage());
}else{
out.println("error: query instance is null!");
}
%>
5. 查询线程类
package org.stephencat.thread;
import org.stephencat.ws.*;
/**
* 查询线程
* @author stephen
*
*/
public class QueryThread implements Runnable {
/**
* 查询时出现的异常
*/
private Exception exception = null;
/**
* 查询获得的结果
*/
private String result = null;
public void run(){
// 执行查询
try{
this.result = ServiceClient.getAllTrips();
}catch (Exception e) {
this.exception = e;
}
}
/**
* @return the exception
*/
public Exception getException() {
return exception;
}
/**
* @param exception the exception to set
*/
public void setException(Exception exception) {
this.exception = exception;
}
/**
* @return the result
*/
public String getResult() {
return result;
}
/**
* @param result the result to set
*/
public void setResult(String result) {
this.result = result;
}
}
import org.stephencat.ws.*;
/**
* 查询线程
* @author stephen
*
*/
public class QueryThread implements Runnable {
/**
* 查询时出现的异常
*/
private Exception exception = null;
/**
* 查询获得的结果
*/
private String result = null;
public void run(){
// 执行查询
try{
this.result = ServiceClient.getAllTrips();
}catch (Exception e) {
this.exception = e;
}
}
/**
* @return the exception
*/
public Exception getException() {
return exception;
}
/**
* @param exception the exception to set
*/
public void setException(Exception exception) {
this.exception = exception;
}
/**
* @return the result
*/
public String getResult() {
return result;
}
/**
* @param result the result to set
*/
public void setResult(String result) {
this.result = result;
}
}