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

2016-02-19 20:24 4 1 收藏

下面,图老师小编带您去了解一下高级:使用异步Servlet扩展AJAX应用程序,生活就是不断的发现新事物,get新技能~

【 tulaoshi.com - 编程语言 】

  作为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应用程序。

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

  此问题的一种解决方案是创建一个扩展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;  
   } 
  }
   

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

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

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

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

来源:http://www.tulaoshi.com/n/20160219/1623593.html

延伸阅读
标签: Web开发
一、简介 AJAX,一个异步JavaScript和XML的缩略词,是最近出来的技术词语。异步意味着你可以经由超文本传输协议(HTTP)向一个服务器发出请求并且在等待该响应时继续处理另外的数据。这就意味着,例如,你可以调用一个服务器端脚本来从一个数据库中以XML方式检索数据,把数据发送到存储在一个数据库的服务器脚本,或者简单地装载一个XML文件以...
阅读提要 AJAX,一个异步JavaScript和XML的缩略词,是当今快速发展的Web开发界十分热门的技术。在这项新技术提供巨大能力的同时,它也燃发了在"Back"按钮问题上的不容置疑的争论。本文作者将向你解释怎样在真实世界中使用AJAX以及怎样在一个工程中评估它的价值。在你读完本文后,你就会明白什么是AJAX,在什么情况下,为什么以及怎样使用这...
标签: Web开发
<h1 使用Ajax开发web应用程序</h1 <p 这个页面演示了AJAX技术如何通过动态读取一个远程文件来更新一个网页的内容--不需要任何网页的重新加载。注意:这个例子对于禁止js的用户来说没有效果。</p <p 这个页面将演示如从取回并处理成组的XML数据。被取回的数据将会以表格形式输出到底下。 <a href="#" onclick="ajaxRead('data_2....
标签: Web开发
新增加的内容,首先是两个新变量的声明:“subAry”和“subAryLen”。它们和之前的变量“dataArray”和“dataArrayLen”类似,除了它们指向不同的数组(特别是它们将指向那些“task”元素-当“dataArray”和“dataArrayLen”指向“pet”元素的时候)。 我们也改变了变量“insertData”的初始值-我们增加了一个表格头(<th )给我们的“task...
标签: Web开发
在过去,由于为了获得新数据而不得不重新加载web页面(或者加载其他页面)导致web应用程序发展被限制。虽然有其他方法可用(不加载其他页面),但是这些技术都没有被很好地支持而且有bug成灾的趋向。在过去的几个月里,一个过去并不被广泛支持的技术已经被越来越多的web冲浪者(web surfers??是指浏览器还是浏览者?)所接受,它给了开发者更...

经验教程

915

收藏

42
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部