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

原创 2006年05月25日 22:59:00

作为Web应用程序模型的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个用户使用该applet,那么就有1000个执行线程几乎是在空等着发送事件通知到客户端。当然了,还有其它方法,比如从applet或AJAX应用程序构建轮询机制来定期检查新数据。而如果不经常接收到数据,那么轮询就显得无用了,而且还浪费了服务器资源,占用了执行线程。反之,服务器可以定期轮询,将事件传播回客户端,并维护套接字线程,而无需使用持久性执行线程。这非常类似于Java NIO的运行方式。理想情况下,我们都希望构建一个从服务器“异步”接收事件通知而无需在服务器端使用持久性执行线程的应用程序,不管它是一个applet还是一个基于AJAX的薄Web应用程序。

此问题的一种解决方案是创建一个扩展FutureResponseServlet类的servlet。浏览器建立了到FutureResponseServlet类的单一连接,并在另一个线程中将它自身注册为一个监听程序。只要在服务器端接收到一个事件,线程就向客户端通知该事件。服务器与客户端保持异步,无需使用持久性执行线程。该模型可扩展用于多个并发用户的情况。

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

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Stack; 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; 
import weblogic.servlet.FutureResponseServlet;
import weblogic.servlet.FutureServletResponse; 
// An AsynchronousServlet that handles HTTP requests from a "separate" thread and
// not the execute thread used to invoke this servlet.
public class AsynchronousServerResponseServlet extends FutureResponseServlet {  
 
 private final Notifier notifier;
 
 public AsynchronousServerResponseServlet() {   
  this.notifier = new Notifier();   
  this.notifier.start();  
 }   
 
 public void service(HttpServletRequest request, FutureServletResponse response) throws IOException,ServletException {    
  // push this client's request to a buffer and return immediately.   
  // asynchronous processing occurs in the run method of the Notifier Thread   
  notifier.poll(request, response);  
 }   
 
 class Notifier extends Thread {    
  private static Stack clients = new Stack();    
  void poll (HttpServletRequest request, FutureServletResponse response) {    
   clients.push(new Client(request, response));   
  }    
  
 public void run() {    
  while (!clients.empty()) {     
   Client client = null;     
   try{      
    client = (Client) clients.pop();      
    PrintWriter pw = client.response.getWriter();      
    for(int j = 0; j < 10; j++) {       
     pw.println("Time is:" + new Date() + "");       
     pw.flush();
    }      
    pw.close();     
   }
   catch(Throwable t) {      
    t.printStackTrace();     
   }
   finally {      
    try {      
     client.response.send();       
    }
    catch(IOException ioe) {      
     ioe.printStackTrace();      
    }     
   }     
  }   
 }  

// inner class that holds o-n to the clients http request and response  
class Client {   
 private HttpServletRequest request;   
 private FutureServletResponse response;    
 private Client(HttpServletRequest request, FutureServletResponse response) {    
  this.request = request;    
  this.response = response;   
 }  
}

可以看出,该例子非常简单。AsynchronousServerResponseServlet类扩展了FutureResponseServlet,并重写了service方法。只使用一个线程(即Notifier类)来处理所有的客户端连接响应。对于每个HTTP请求,servlet向Notifier线程注册套接字连接,然后返回。异步事件被交付给客户端,而持久性套接字连接被维持。

单个线程可管理多个客户端连接!run()方法可用于根据某种消息选择条件回调事件到客户端。该例子只执行了一个服务器端的push操作,有些过分简单了。线程池可被用于某些类型的事件处理。

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

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

1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111...
  • zgqtxwd
  • zgqtxwd
  • 2008年04月24日 02:30
  • 95

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

作为Web应用程序模型的AJAX的出现使服务器端的面貌发生了巨大的变化。用户对着Web页面填写表单并单击提交按钮转到下一个链接的典型Web使用模式现在正在转变为更先进的客户端JavaScript以及功...
  • leimbag
  • leimbag
  • 2007年06月18日 13:10
  • 446

高级:使用异步Servlet扩展AJAX应用程序

 作为Web应用程序模型的AJAX的出现使服务器端的面貌发生了巨大的变化。用户对着Web页面填写表单并单击提交按钮转到下一个链接的典型Web使用模式现在正在转变为更先进的客户端JavaScript以及...
  • kinglino520
  • kinglino520
  • 2009年07月23日 12:36
  • 152

Ajax 异步处理 servlet 交互

首先 我要说   very 简单  两个事儿 1、
  • u010310183
  • u010310183
  • 2014年07月26日 15:54
  • 826

ajax+servlet+fastjson+js实现异步刷新

1.大概从08年开始ajax技术开始 流行,   出现那种 html 静态页面 可以 与 后台交互数据的情况                     今天专门 探究 ajax 基础极速入门  2. 首...
  • sinat_27639721
  • sinat_27639721
  • 2016年09月30日 11:16
  • 1309

ajax异步文件上传,servlet处理,含demo

ajax上传组件源自于http://www.phpletter.com/Demo/AjaxFileUpload-Demo/,用的jquery 不过它服务器端用的是php,原理都是一样的,我改成了jav...
  • thc1987
  • thc1987
  • 2013年11月11日 18:02
  • 31022

使用jquery.form.js+servlet实现文件异步上传

之前一直用ajaxfileupload上传文件,但是无法解决跨域问题,用form表单提交文件又无法异步上传 现在用jqueryform就可以完美解决上面的问题 页面代码 Tit...
  • oshidi
  • oshidi
  • 2016年07月27日 16:44
  • 371

使用ajaxfileupload.js异步上传文件到Servlet

前段时间帮同学做的毕业设计,好吧又是帮人做= =。。。需要上传文件,在这里使用了ajaxfileupload.js进行异步的上传文件到Servlet ,后台保存了文件以后通过JSON返回文件路径到前...
  • y353027520dx
  • y353027520dx
  • 2015年03月28日 16:13
  • 2352

JSP+Servlet+Ajax实现后台异步检验用户信息实例

下面介绍JSP前台表单内容通过Ajax异步提交到后台Servlet进行校验(校验方式多种,包括提取数据库信息,校验用户名是否重复等),异步在JSP表单页面显示校验结果信息的基本过程。  一、说明...
  • a771948524
  • a771948524
  • 2013年12月03日 11:10
  • 1480

jsp+servlet+ajaxfileupload.js 实现异步上传

java代码: package yaSoft.Util; import java.io.File; import java.io.IOException; import java.io.PrintW...
  • liujava621
  • liujava621
  • 2014年12月30日 18:10
  • 2805
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:使用异步Servlet扩展AJAX应用程序
举报原因:
原因补充:

(最多只允许输入30个字)