龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > web编程 > Javascript编程 >

基于JMX通知框架的AJAX深度开发(1)(2)

时间:2013-03-06 14:58来源:未知 作者:admin 点击:
分享到:
五、广播Admin MBean属性 管理和托管UserWeb Mbeans可以进行独立地设置-这给任何一个J2EE服务器一个本地化的AJAX响应。然而,一个普通操作,管理和支持(OA' o
五、广播Admin MBean属性

管理和托管UserWeb Mbeans可以进行独立地设置-这给任何一个J2EE服务器一个本地化的AJAX响应。然而,一个普通操作,管理和支持(OA&M)支持模式将设置admin MBean的属性,然后使用通知模型把这些属性广播到远程应用程序服务器上的MBeans,以备随后的AJAX检索之用。

因为该UserWeb MBean是基于ApplicationMBean-它扩展了javax.management.NotificationBroadcasterSupport,所以该基础结构正适合于由UserWeb MBean来通知所有的听者。因此,管理员设置相关的MBean属性(使用HTMLAdaptor)并且点击BroadcastState(见图2)。


图2 使用HTMLAdaptor看到的MBean视图

因而,UserWeb.broadcastState()方法被执行-它同步地通知所有的听者有关admin MBean的状态:

public void broadcastState() throws Exception {
 try {
Notification n = new Notification

("alert.broadcast", "ExampleApp:Name=UserWeb", 0);
n.setUserData(new UserWeb(this));
this.sendNotification(n);
 }
 catch (Exception e) {
throw e;
 }
}

因为数据在网络上是串行化传输的,所以这种并非暂时的对象图必须是可串行化的。

六、使用听者接收来自MBean Props的通知

所谓的事件听者就是ManagementListener Singleton。在管理服务器上的JMX通知框架远程调用ManagementListener中的handleNotification()方法-该方法存在于每个OLTP簇JVMs(它们是在服务器启动时注册的)上的每一个听者之中:

public void handleNotification(Notification notification, Object handback) {
System.out.println("Received alert: " + notification.getType());
//取得来自通知的事件userdata
Object userData = notification.getUserData();
if (userData instanceof UserWeb) {
 //来自于destin8 Web
 UserWeb WebVo = (UserWeb)userData;
 UserWebMBeanHelper helper = MBeanHelperFactory.getWebHelper();
 //使用MbeanHelper从值对象获取数据并放入本地MBean中
 helper.setAlertMessage(WebVo.getAlertMessage());
 helper.setAlertStatus(WebVo.getAlertStatus());
 helper.setCallBack(WebVo.getCallBack());
 helper.setRefreshAlertStatus(WebVo.getRefreshAlertStatus());
}
}

"master" UserWeb数据被置入本地用户Web MBean中-经由它的MBean助理来实现。因而,每个管理服务器被用master UserWeb状态所更新。这就是JMX元素所具有的功能。

七、 管理状态的AJAX请求

要使浏览器客户端支持AJAX,需要具备如下:

main.jsp-被装配的JSP页面,它能够检查(JMX)警告状态并向服务器查询警告。这个.jsp文件包括admin.js

admin.js-这是一个JavaScript实用程序,它使用XMLHttpRequest来向服务器查询管理状态,分析XML响应,并且重画屏幕的"status"区域

被包含在main.jsp中的JavaScript描述如下:<script type="text/javascript" src="./js/admin.js" ></script>

不是连续地查询,而是只有启动浏览器警告功能时我们才进行查询。我们使用UserWebMBeanHelper来检查这个功能。如果该功能被启动,那么当页面加载时,JavaScript函数initAdmin()将被调用:

<%
if (MBeanHelperFactory.getWebHelper().isAlertEnabled()) {
%>
<body bgcolor="#F4FFE4" onload="initAdmin();">
<%
} else {
%>
<body bgcolor="#F4FFE4">
<%
}
%>

重画的'status'屏幕区域定义如下:<span id="adminBanner" class="style1"></span>

"adminBanner"将被使用来标记可重画的区域-当分析XML响应并提取消息时。

这个initAdmin()方法调度一个JavaScript方法trapAlert()-这个方法在callbackTimeout毫秒后执行:

function setCallback() {
 callBack = setTimeout('trapAlert()',callbackTimeout);
}
function initAdmin() {
 setCallback();
}

注意,是由trapAlert()方法来实现启动XMLHttpRequest:

function trapAlert() {
 if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
 } else if (window.ActiveXObject) {
req = new ActiveXObject("Microsoft.XMLHTTP");
 }
 req.onreadystatechange = processRequest;
 req.open("GET", './admin?reqid=0', true);
 req.send(null);
}

在此,HTTP GET用来读数据(只使用了一个小的请求参数),并且目标是admin servlet。这个请求是异步的,并且当请求状态变化时,processRequest JavaScript函数被调用: req.onreadystatechange = processRequest;

在继续处理前等待一个响应,这看上去似乎非常合理;然而,如果一个网络或服务器问题导致一个事务无法完成,那么你要冒着使你的脚本挂起来的危险。相比之下,一个相应于onreadystatechange事件的异步调用更为灵活些。

在请求完成时,processRequest事件处理器被调用:

function processRequest() {
 if (req.readyState == 4) {
if (req.status == 200) {
 parseMessages();
}
....
setCallback();//只有完成时才这样做
 }
}

列表1显示了所有可用的状态码。当请求完成并且返回HTTP状态代码200(OK)时,parseMessages()方法被调用以从XML消息中提取数据。然后,再次调度trapAlert()方法。如果XML响应有一个不同的重试间隔,那么这个值会由parseMessages()函数设置。

八、分析XML响应并重画屏幕

parseMessages()函数首先提取XML响应:response = req.responseXML;

然后,它提取有关警告状态,警告文本和重试间隔等的元素:

itemStatus = response.getElementsByTagName('status')

[0].firstChild.nodeValue;
itemText = response.getElementsByTagName('textBody')

[0].firstChild.nodeValue;
callbackTimeout = parseInt(response.getElementsByTagName('callBack')

[0].firstChild.nodeValue);

然后,警告文本被重画到adminBanner文档元素(见上):document.getElementById("adminBanner").innerHTML= itemText;

该警告消息显示在如图3所示的屏幕上。


图3 重画的屏幕

九、Servlet格式化XML响应

为了使浏览器把管理警告显示给用户,需要使用XMLHttpRequest来请求管理状态。

当浏览器发送请求时,该servlet使用MBean助理来检查警告状态并且,如果一警告可用,即构建一个XML文档作为响应。

如果没有返回状态,那么响应状态被设置如下:response.setStatus(HttpServletResponse.SC_NO_CONTENT);

否则,该文本/XML响应类型被设置为:response.setContentType("text/xml");

列表2显示了完整的servlet方法。

当该servlet被调用并且返回XML内容时,控制台应该打印出:

Received alert: alert.broadcast
<message>
<status>1</status>
<textBody>
<![CDATA[System Down in 10 Minutes]]>
</textBody>
<callBack>10000</callBack>
</message>

十、容量建模和安全性

因为AJAX以有趣的方式开通了架构,所以存在两个关键方面要求加以考虑:

容量建模

安全性

当然,缓冲和响应消息类型(XML或文本)也都是比较重要的。

十一、容量建模

支持AJAX的丰富的客户端不必再如以前那样频繁地提交请求。但是随着XMLHttpRequest异步地执行在浏览器端,向服务器发出的HTTP请求的数目也会相应于重试间隔而有所增加。

再试间隔(思考时间)=20秒

连接的用户数=5000

事务每秒(TPS)=5000/20=250

我们期望一个由HTTP用户基所产生的额外的每秒能够实现250次的请求(事务)。

当然,这依赖于在服务器上的这些请求所完成的任务来提高响应时间上的潜力。在我们的实例中,每个请求必须查找MBean属性并且格式化一个XML响应,但是该响应很小而且MBean处理是在本地内存中。由于每个Web服务器线程每秒能够处理大约200个GET请求,以及用户横跨一个大约运行着200个线程的J2EE服务器来请求平衡加载,所以增加的加载并不太重要。

还应注意,当建模AJAX架构时,增加的加载数可能随着带宽的减少而有所偏移。

十二、安全性

假定你只要求WebUser组中的用户能够存取该admin servlet,情况会怎样呢?

如果仅是被认证的用户才能存取admin servlet,那么XMLHttpRequest将以该用户身份运行-如果该用户已经认证。

例如,一旦用户Joe登录进这个应用程序,并且Joe是一个WebUser组的成员,那么XMLHttpRequest将能激活admin servlet。

把下列代码添加到admin servlet将会确认被认证的主题,并分别返回true和Joe:

request.isUserInRole("WebUser");
request.getRemoteUser();

十三、缓冲

一些用户已经发现IE会缓冲来自AJAX请求的响应;这可能是由于浏览器/页面设置,但是一个强制性的解决办法是为该URL加上时间印戳:

var urlstr = "./admin?reqId=0&ts=" + new Date().getTimeStamp();

十四、用不用XML?

一些AJAX设计者欣然弃用XML而发送以普通文本形式的响应:response.setContentType("text/plain");

这明显要依赖于你的客户端需求和客户与所需求的数据之间的耦合程度。一个简单的文本响应对于一个文本警告就足够了;然而,本文中XML模型的优点在于,响应数据可以被进一步详细描述从而提炼状态和状态相关的数据。本文向你展示了怎样分析一更复杂的响应-客户可能必须编码以进行接收之。

十五、 结论

AJAX代表了一些新型的架构机会,然而它们不应该被丰富的客户端功能所遮蔽。本文在衡量了AJAX所提供的优点的同时,也强调了其对于容量和安全方面的技术要求-这是使用这种新型技术所必须要求的。

(责任编辑:铭铭 mingming_ky#126.com TEL:(010)-68476636)


精彩图集

赞助商链接