使用异步Servlet扩展AJAX应用程序

使用异步Servlet扩展AJAX应用程序,第1张

使用异步Servlet扩展AJAX应用程序,第2张

AJAX作为一种Web应用模型,给服务器端带来了巨大的变化。用户在网页前填写表单并点击提交按钮进入下一个链接的典型Web使用模式现在正转变为更高级的客户端JavaScript和更丰富的用户界面。只要表单被操作,比如单击一个复选框、按一个键或者将鼠标移动到一个选项卡上,用户界面就会不断地与服务器进行交互。

考虑从客户端传输到服务器的数据量。从可用性的角度来看,用户无需安装任何东西就可以在瘦客户端浏览器上获得丰富的用户界面。然而,当这些应用程序在服务器端扩展时,将会付出代价。AJAX应用程序的典型容量规划数量可能是标准Web应用程序的3到4倍。

有人可能会问:这对WebLogic Server有什么影响?发送到WebLogic的每个HTTP请求都使用一个执行线程。根据AJAX编程的性质以及许多短期请求会以轮询的形式不断发送的事实,这种行为模式可能会导致大量客户端请求不断冲击服务器。多年来,WebLogic已经考虑到了这个问题,并建立了一个非常好的功能,即FutureResponseServlet。这个范例基于异步servlet的概念。从版本6.1开始,该特性允许开发人员从服务器提供真正的异步通知,而不是在客户端训练事件并在服务器端使用执行线程。在9.x之前,BEA并不急于公开这个类。

如何在现实中使用这个类?让我们看一个例子。假设业务需求是构建一个基于Web的应用程序,在不刷新浏览器的情况下将数据近乎实时地发送到服务器。这样的应用程序可以向服务器提交一个需要很长时间处理的请求,并且仍然可以接收关于其状态的异步事件并侦听事件。从技术角度来看,有很多方法可以实现这一点。其中一种方法是使用与Java Servlet通信的Java Applet来获取异步信息。这是一个很好的方法,但是对于用户来说很不方便,因为他们必须下载一个JVM和一个applet到浏览器。此外,您必须维护从客户端到服务器的持久套接字连接,以接收异步消息。想象一下,如果有1000个用户在使用小程序,那么几乎在空就会有1000个执行线程等待向客户端发送事件通知。当然还有其他的方法,比如从applet或者AJAX应用中构建轮询机制,定期检查新数据。但是如果不经常接收数据,那么轮询是没有用的,而且浪费服务器资源,占用执行线程。相反,服务器可以定期轮询,将事件传播回客户端,并维护套接字线程,而不使用持久执行线程。这与Java NIO的工作方式非常相似。理想情况下,无论是applet还是基于AJAX的瘦Web应用程序,我们都希望构建一个从服务器“异步”接收事件通知的应用程序,而不使用服务器端的持久执行线程。

以下是引号片段:
import Java . io . io exception;
导入Java . io . printwriter;
导入Java . util . date;
导入Java . util . stack;
导入javax . servlet . servlet exception;
导入javax . servlet . http . http servlet request;
导入WebLogic . servlet . futureresponseservlet;
导入WebLogic . servlet . futureservlet response;
//一个异步Servlet,它处理来自一个“单独”线程的HTTP请求,而
//不是用于调用该servlet的执行线程。
公共类asynchronousserverpresponseservlet扩展FutureResponseServlet {

私有final Notifier notifier

public asynchronousserverpresponseservlet(){
this . Notifier = new Notifier();
this . notifier . start();
}

public void service(http servvletrequest请求,FutureServletResponse响应)抛出IOException,ServletException {
//将此客户端的请求推送到缓冲区并立即返回。
//异步处理发生在通知线程的run方法中
notifier.poll(request,response);
}

类通知程序扩展线程{
私有静态堆栈clients = new Stack();
void poll(http servlet request请求,FutureServletResponse响应){
clients.push(新客户端(请求,响应));
}

public void run(){
while(!clients . empty()){
Client Client = null;
try {
Client =(Client)clients . pop();
PrintWriter pw = client . response . getwriter();
for(int j = 0;j < 10j++){
pw . println(" Time is:"+new Date()+" ");
pw . flush();
}
pw . close();
}
catch(Throwable t){
t . printstacktrace();
}
最后{
try {
client . response . send();
}
catch(io exception ioe){
ioe . printstacktrace();
}
}
}
}
}
//保存客户端http请求和响应的o-n的内部类
类Client {
private http servlet request请求;
私有FutureServletResponse响应;
私有客户端(HttpServletRequest请求,FutureServletResponse响应){
this . request = request;
this . response = response;
}
}
这个问题的一个解决方案是创建一个servlet来扩展FutureResponseServlet类。浏览器建立到FutureResponseServlet类的单个连接,并将自己注册为另一个线程中的侦听器。一旦服务器端接收到事件,线程就通知客户端该事件。与服务器和客户端保持异步,不使用持久执行线程。该模型可以扩展到多个并发用户的情况。

本文不打算介绍如何构建AJAX应用程序。关于这个主题已经有很多文章了。本文重点讨论表示层(如AJAX、applet或任何前端应用)异步处理的重要性。清单1显示了一个例子。

如你所见,这个例子非常简单。asynchronousserverpresponseservlet类扩展了FutureResponseServlet并重写了服务方法。只有一个线程(即通知程序类)用于处理所有客户端连接响应。对于每个HTTP请求,servlet向通知程序线程注册套接字连接,然后返回。异步事件被传递给客户端,同时保持持久的套接字连接。

一个线程可以管理多个客户端连接!run()方法可用于根据特定的消息选择条件将事件回调到客户端。这个例子只执行一个服务器端的推送操作,有点太简单了。线程池可用于某些类型的事件处理。

总而言之,在处理长时间运行的任务时,FutureResponseServlet是一个很好的特性。它允许开发人员提高性能,在独立的线程中处理响应,并最小化开销。在构建异步应用程序时,此方法支持可伸缩性。

位律师回复
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » 使用异步Servlet扩展AJAX应用程序

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情