java实现System.Web.UI.ICallbackEventandler

早在ASP.NET 2.0 beta1时.NET就已经包含了一个异步技术叫Callback。本文将使用Java/JSP+JavaScript实现ASP.NET的Callback技术。

1.ASP.NET 2.0的Callback技术
java实现System.Web.UI.ICallbackEventandler
ASP网页必须实现ICallbackEventHandler的RaiseCallbackEvent方法和GetCallbackResult方法
RaiseCallbackEvent方法负责接收Client端JavaScript所送进来的参数。GetCallbackResult负责返回结果传给Client段。
例如
Public partial class ClientCallbackSimple:System.Web.UI.page, System.Web.UI.ICallbackEventHandler
{
Public void RaiseCallbackEvent(string arg){
//do something.
}
Public sting GetCallbackResult(){
//do someting
}
}
ASP
<title>Callback Test</title>
<script type="text/JavaScript">
function OnCallback(data)
{
Results.innerText=data;
}
</script>
</head>
<body>
<div>
<form id="form1" action="#">
<input type="text" id="arg" value="0"/>
<input type=buttonvalue=Callbackonclick=<%=ClientScript.GetCallbackEventReference(this,document.form1.arg.value,OnCallback,null) %> />
<div ID="Results"></div>
</form>
</div>
</body>
</html>
其中ClientScript类负责注册Callback JavaScript函数。当按钮被点击后,程序会调用Server的RaiseCallbackEvent 方法和GetCallbackResult 方法,之后返回Client段,并调用OnCallback函数。
2.Callback的java实现
1.ICallbackEventHandler接口
接口定义为:
package org.colimas.callback;
publicinterface ICallbackEventHandler {
public Object RaiseCallbackEvent(String arg);
}
本文删掉GetCallbackResult方法,RaiseCallbackEvent方法直接返回一个结果。
2.EventHandler工厂
CallbackEventFactory类负责生成EventHandler实例。
package org.colimas.callback;
import java.util.HashMap;
publicclass CallbackEventFactory {
privatestatic HashMap handlers;
//singleton
private CallbackEventFactory(){
}
/**
*init
*@parampath
*/
publicstaticvoid init(String path){
handlers=new HashMap();
Object value;
try {
//put all handles into handlers;
//following is a sample by only one handle.
value = Class.forName("org.colimas.handlers.ReadData").newInstance();
handlers.put("read_data", value);
} catch (InstantiationException e) {
// TODO自動生成された catch ブロック
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO自動生成された catch ブロック
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO自動生成された catch ブロック
e.printStackTrace();
}
}
/**
*geteventhandlerbyhandlename
*@paramhandlerName
*@return
*/
publicstatic ICallbackEventHandlergetEventHandler(String handlerName){
return (ICallbackEventHandler)handlers.get(handlerName);
}
}
3.Callback Servlet
初始化CallbackEventFactory
获得Request参数,并根据参数获得EventHandler实例,调用RaiseCallbackEvent并返回结果给客户端。
package org.colimas.callback;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class for Servlet: CallbackServlet
* call event handler.
* return result.
*
*/
public class CallbackServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
private static final long serialVersionUID = 1L;
/**
* init CallbackEventFactory
*/
public void init() throws ServletException {
super.init();
CallbackEventFactory.init(this.getInitParameter("handler_path"));
}
/**
* process request
* get event handle by name
* call event handle
* return result to resposne.
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String handlerName=(String)request.getParameter("handle");
String arg=(String)request.getParameter("arg");
if(arg==null)
arg="";
ICallbackEventHandler eventHandler=CallbackEventFactory.getEventHandler(handlerName);
String result=(String)eventHandler.RaiseCallbackEvent(arg);
response.getWriter().print(result);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
}
部署Servlet
<servlet>
<servlet-name>CallbackServlet</servlet-name>
<display-name>CallbackServlet</display-name>
<description></description>
<servlet-class>
org.colimas.callback.CallbackServlet
</servlet-class>
<init-param>
<param-name>handler_path</param-name>
<param-value>conf/handlers.properties</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>CallbackServlet</servlet-name>
<url-pattern>/callback</url-pattern>
</servlet-mapping>
4.ClientScript的实现
生成下面JavaScript代码
createXMLHttpRequest('/callback','handle=value&arg=value');
package org.colimas.callback;
/**
*registercallbackevent.
*@authortyrone
*
*/
publicclass ClientScript {
publicstatic String GetCallbackEventReference(String arg,String handle){
StringBuffer js=new StringBuffer();
js.append("createXMLHttpRequest('/callback");
js.append("','handle=");
js.append(handle);
js.append("&arg='+");
js.append(arg+")");
return js.toString();
}
}
5.Common JSP
Common.jsp负责公用代码实现。包括,XmlHttp的实例化,发送URL请求,Server端返回后的Client端OnCallback调用。
<%@ page import="org.colimas.callback.ClientScript" %>
<script type="text/javascript" >
var xmlHttp;
function createXMLHttpRequest(url,query){
if(window.ActiveXObject){
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}else if(window.XMLHttpRequest){
xmlHttp=new XMLHttpRequest();
}
var path="<%=request.getContextPath()%>"+url+"?"+query;
xmlHttp.onreadystatechange=callback;
xmlHttp.open("GET",path,true);
xmlHttp.send(null);
}
function callback(){
if (xmlHttp.readyState==4){
if(xmlHttp.status==200){
var data=xmlHttp.responseText;
OnCallback(data);
}
}
}
</script>
6.测试
创建CallbackEventHandler类,自定义ICallbackEventHandler接口实现,根据Client段传送的参数,计算一个随机数。
package org.colimas.handlers;
import org.colimas.callback.ICallbackEventHandler;
import java.util.Random;
public class ReadData implements ICallbackEventHandler {
public Object RaiseCallbackEvent(String arg) {
if(arg!=null){
String data="";
Random r=new Random();
float f=r.nextFloat()* Float.valueOf(arg).floatValue();
data=new Float(f).toString();
return data;
}
return null;
}
}
创建JSP页面,每个1秒钟,向服务器段请求一次。:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<html>
<meta http-equiv="Pragma" content="no-cache">
<head>
<title>Callback Test</title>
<%@ include file="/jsp/common.jsp" %>
<script type="text/JavaScript">
function DoGet()
{
//Register callbackevent
//createXMLHttpRequest('/callback','handle=read_data&arg='+form1.arg.value);
//注册CallbackEventhandle <%=ClientScript.GetCallbackEventReference("form1.arg.value","read_data")%>;
}
//OnCallback函数定义。
function OnCallback(data)
{
Results.innerText=data;
}
</script>
</head>
<body onload="setInterval('DoGet()',1000)">
<div>
<form id="form1" action="#">
<input type="text" id="arg" value="0"/>
<div ID="Results"></div>
</form>
</div>
</body>
</html>
运行结果:
java实现System.Web.UI.ICallbackEventandlerjava实现System.Web.UI.ICallbackEventandler
每次修改输入框内的值,下面的Text值都回动态改变。