Servlet 3.0的AsyncListener接口

作者:chszs,转载需注明。

博客主页:http://blog.csdn.net/chszs

一、Servlet 3.0介绍

Servlet 3.0作为 JavaEE 6规范中一部分,随着JavaEE 6规范一起公布。

该版本号在前一版本号(Servlet 2.5)的基础上提供了若干新特性用于简化Web应用的开发和部署。当中有几项特性的引入让开发人员感到很兴奋,同一时候也获得了Java社区的一片赞誉之声:

1)异步处理支持

在Servlet 3.0版本号之前,Servlet线程须要一直堵塞,直到业务处理完毕才干再输出响应,最后才结束该Servlet线程。

而有了异步处理特性,Servlet线程不再须要一直堵塞。在接收到请求之后,Servlet线程能够将耗时的操作委派给还有一个线程来完毕。自己在不生成响应的情况下返回至容器。针对业务处理较耗时的情况,这能够大幅度减少server的资源消耗,而且提高并发处理速度。

2)新增的注解支持

Servlet 3.0版本号新增了若干注解,用于简化 Servlet、过滤器(Filter)和监听器(Listener)的声明,这使得web.xml部署描写叙述文件不再是必选项了。

3)功能可插拔支持

二、server推技术

在Servlet 2.5中,页面发送一次请求是顺序运行的,即在Servlet的Service中开启一个线程,线程处理后的结果是无法返回给页面的,Servlet运行完毕后,Response就关闭了,无法将后台更新数据即时更新到页面端。

server推技术的实现

1)定时发送请求,页面有刷新,不友好

2)Ajax轮询,然后通过js更新页面数据

相比前者尽管友好。訪问量太大时,server会添加压力。小型应用能够考虑用

3)反向Ajax(即Comet技术)

利用Http 1.1长连接的特性。即通过轮询,但client每次发送请求时server不会马上返回响应,而是等待server有新数据时才返回或者没有新数据而连接超时返回。

相比于ajax轮询。减少了服务端压力,但一个缺点,不是全部浏览器都支持。

在Servlet 3.0中提供了异步支持,当数据返回页面后,Request并没有关闭,当server端有数据更新时,就能够推送了。

三、Servlet 3.1规范的改进

GlassFish 4.0以上版本号领先实现了Servlet 3.1规范。Servlet 3.1规范的新特性有:

1)更便利的注解支持

提供了@WebServlet、@WebFilter、@WebListener、@WebInitParam等注解的支持

2)可插拔的设计

Web模块化:能够将一个项目分成N个模块,然后通过扫描模块下的META-INF/web-fragment.xml进行装配。

容器启动时的可插拔:使用ServletContainerInitializer实现,能够在容器启动时自己主动回调其onStartup方法,插入一些功能。

零XML配置的类SpringMVC:使用ServletContainerInitializer即SpringMVC注解配置实现无XML化的SpringMVC配置。

3)异步处理支持

Servlet的异步支持:

- 通过Servlet提供的异步支持完毕了Comet:Streaming(长连接)和Ajax长轮询

- 使用Servlet提供的AsyncListener进行状态回调

- 最后通过Ajax长轮询实现了一个聊天室功能

SpringMVC对Servlet的异步支持:

- 使用SpringMVC框架提供的异步支持实现Comet:Streaming(长连接)和Ajax长轮询

- 使用SpringMVC框架提供的Callable实现异步计算

- 使用SpringMVC框架提供的DeferredResult实现延迟结果(实现Ajax长轮询)

- Spring框架没有提供长连接实现,详细还得使用原生支持

- 最后通过ajax长轮询实现了一个聊天室功能

4)非堵塞I/O

5)HTTP协议升级

四、Servlet的监听器

Servlet的监听器即Listener,它能够监听来自client的请求、完毕server端的操作等。通过监听器,能够自己主动触发一些操作。比方:监听在线用户的数量,当添加一个HttpSession时,就触发一个sessionCreated(HttpSessionEvent se)方法。这样就能够给在线人数加1了。

经常使用的监听器接口有:

1. ServletContextListener

监听ServletContext。当创建ServletContext时。触发contextInitialized(ServletContextEvent sce)方法;当销毁ServletContext时。触发contextDestroyed(ServletContextEvent sce)方法。

2. ServletContextAttributeListener

监听对ServletContext属性的操作,比方添加、删除、改动属性。

3. HttpSessionListener

监听HttpSession的操作。当创建一个Session时,触发session Created(HttpSessionEvent se)方法。当销毁一个Session时,触发sessionDestroyed(HttpSessionEvent se)方法。

4. HttpSessionAttributeListener

监听HttpSession属性的操作。当在Session添加一个属性时,触发attributeAdded(HttpSessionBindingEvent se)方法;当在Session删除一个属性时。触发attributeRemoved(HttpSessionBindingEvent se)方法。当在Session属性被又一次设置时。触发attributeReplaced(HttpSessionBindingEvent se)方法。

Servlet 3.0的监听器跟Servlet 2.5的监听器区别不大。唯一的区别就是添加了对注解的支持。在3.0曾经,监听器的配置须要配置到web.xml文件。在3.0中,监听器的配置既能够放入web.xml文件,还能够使用注解进行配置。对于使用注解的监听器就是在监听器类上使用@WebListener进行凝视,这样Web容器就会把这个类当成是一个监听器进行注冊和使用。

假设是採用web.xml配置文件的方式,那么就是这样:

<listener>
<listener-class>com.xxx.SessionListener</listener-class>
</listener>
<listener>
<listener-class>com.xxx.ContextListener</listener-class>
</listener>

五、Servlet 3.0的异步处理

有时Filter或Servlet在生成响应之前必须等待一些耗时的操作结果以便完毕请求处理。而在Servlet中。等待是一个低效的操作。由于这是堵塞操作。会白白占用一个线程或其它一些受限资源。

很多线程为了等待一个缓慢的资源(如数据库连接)经常发生堵塞。可能引起线程饥饿,从而减少整个Web容器的服务质量。

Servlet 3.0引入了异步处理请求的能力,使线程能够返回到容器。从而运行很多其它的任务。当開始异步处理请求时,还有一个线程或回调能够或产生响应。或调用完毕(complete)或请求分派(dispatch)。这样。它能够在容器上下文使用AsyncContext.dispatch方法运行。

一个典型的异步处理事件顺序是:

1. 请求被接收到,通过一系列如用于验证的标准Filter之后被传递到Servlet。

2. Servlet处理请求參数及内容体从而确定请求的类型。

3. 该Servlet发出请求去获取一些资源或数据。

4. Servlet不产生响应并返回。

5. 过了一段时间后,所请求的资源变为可用,此时处理线程继续处理事件。要么在同一个线程,要么通过AsyncContext分派到容器中的某个资源上。

@WebServlet凝视和@WebFilter凝视有一个属性——asyncSupported,是布尔类型,默认值为false。当asyncSupported设置为true,则应用通过运行startAsync能够启动一个单独的线程进行异步处理,并把请求和响应的引用传递给这个线程,然后退出原始线程所在的容器。这意味着响应将遍历(相反的顺序)与进入时同样的过滤器(或过滤器链)。

直到AsyncContext调用complete时响应才会被提交。假设异步任务在容器启动的分派之前运行。且调用了startAsync并返回给容器,此时应用需负责处理请求和响应对象的并发訪问。

从一个 Servlet分派时,把asyncSupported=true设置为false是同意的。这样的情况下。当Servlet的Service方法不支持异步退出时,响应会被提交,且容器负责调用AsyncContext的complete。以便全部感兴趣的AsyncListener能得到触发通知。过滤器作为清理要完毕的异步任务持有资源的一种机制。也应该使用AsyncListener.onComplete触发。

从一个同步Servlet分派到还有一个异步Servlet是非法的。只是与该点不同的是当应用调用startAsync时将抛出IllegalStateException。这将同意 servlet 仅仅能作为同步的或异步的 Servlet。

应用在一个与初始请求所用的不同的线程中等待异步任务直到能够直接写响应,这个线程不知道不论什么过滤器。假设过滤器想处理新线程中的响应,那就必须在处理进入时的初始请求时包装 response。而且把包装的 response 传递给链中的下一个过滤器,并终于交给 Servlet。因此,假设响应是包装的(可能被包装多次。每个过滤器一次),而且应用处理请求并直接写响应,这将仅仅写响应的包装对象,即不论什么输出的响应都会由响应的包装对象处理。

当应用在一个单独的线程中读请求时。写内容到响应的包装对象,这事实上是从请求的包装对象读取。并写到响应的包装对象,因此对包装对象操作的全部输入及(或)输出将继续存在。假设应用选择这样做的话,它将能够使用 AsyncContext 从一个新线程发起到容器资源的分派请求。

这将同意在容器范围内使用像 JSP 这样的内容生成技术。

六、异步监听器接口AsyncListener

Servlet 3.0为异步处理提供了一个监听器,使用AsyncListener接口表示。此接口负责管理异步事件。它能够监控例如以下四种事件:

1. 异步线程開始时。调用AsyncListener的onStartAsync(AsyncEvent event)方法。

2. 异步线程出错时,调用AsyncListener的onError(AsyncEvent event)方法。

3. 异步线程运行超时,则调用AsyncListener的onTimeout(AsyncEvent event)方法。

4. 异步运行完毕时,调用AsyncListener的onComplete(AsyncEvent event)方法;

要注冊一个AsyncListener。仅仅需将准备好的AsyncListener对象传递给AsyncContext对象的addListener()方法就可以。例如以下所看到的:

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res){
AsyncContext actx = req.startAsync();
actx.addListener(new AsyncListener(){
public void onComplete(AsyncEvent event) throws IOException{
// do 一些清理工作或者其它
} public void onTimeout(AsyncEvent event) throws IOException{
// do 一些超时处理的工作或者其它
}
});
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);
executor.execute(new MyAsyncService(actx));
}

Servlet 3.0的AsyncListener接口的更多相关文章

  1. Servlet 4.0 入门

    Java™ Servlet API 是主流服务器端 Java 的基本构建块,也是 Java EE 技术的一部分,例如,用于 Web 服务的 JAX - RS.JSF (JavaServer Faces ...

  2. Servlet 3.0

    Servlet 3.0 作为 Java EE 6 规范体系中一员,随着 Java EE 6 规范一起发布.该版本在前一版本(Servlet 2.5)的基础上提供了若干新特性用于简化 Web 应用的开发 ...

  3. [转]Servlet 3.0 新特性详解

    原文地址:http://blog.csdn.net/xiazdong/article/details/7208316 Servlet 3.0 新特性概览 1.Servlet.Filter.Listen ...

  4. Servlet 3.0 新特性

    Servlet 3.0 作为 Java EE 6 规范体系中一员,随着 Java EE 6 规范一起发布.该版本在前一版本(Servlet 2.5)的基础上提供了若干新特性用于简化 Web 应用的开发 ...

  5. Servlet 3.0 新特性详解

    转自:http://www.ibm.com/developerworks/cn/java/j-lo-servlet30/#major3 Servlet 是 Java EE 规范体系的重要组成部分,也是 ...

  6. servlet 3.0特性说明

    Servlet 3.0 作为 Java EE 6 规范体系中一员,随着 Java EE 6 规范一起发布.该版本在前一版本(Servlet 2.5)的基础上提供了若干新特性用于简化 Web 应用的开发 ...

  7. 【转帖】Servlet 3.0 新特性详解

    http://www.ibm.com/developerworks/cn/java/j-lo-servlet30/ Servlet 3.0 新特性概述 Servlet 3.0 作为 Java EE 6 ...

  8. Servlet 3.0 新特性详解 (转载)

    原文地址:https://www.ibm.com/developerworks/cn/java/j-lo-servlet30/ Servlet 3.0 新特性概述 Servlet 3.0 作为 Jav ...

  9. Java Servlet 3.0 新特性

    Servlet 3.0 新特性概述 Servlet 3.0 作为 Java EE 6 规范体系中一员,随着 Java EE 6 规范一起发布.该版本在前一版本(Servlet 2.5)的基础上提供了若 ...

随机推荐

  1. webdriver高级应用-js操作滚动条

    1.滑动页面的滚动条到页面最下面 2.滑动页面的滚动条到页面的某个元素 3.滑动页面的滚动条向下移动某个数量的像素 #encoding=utf-8 from selenium import webdr ...

  2. requests与urllib 库

    requests库 发送请求: 可以处理所有请求类型:get.post.put.Delete.Head.Options r = requests.get(''https://httpbin.org/' ...

  3. Flask_WTForms源码流程(糙版)

    from flask import Flask, render_template, request, redirect # Form# _fields# validate# validata_name ...

  4. Android 程序 LinearLayout布局 参数layout_weight 探讨

    官方参考文档 对LinearLayout.LayoutParams中的android:layout_weight解释如下:Indicates how much of the extra space i ...

  5. Mark Down 简单标记语言

    MarkDown介绍=============== ## 1.标题分级介绍 #一级标题###三级标题######六级标题 一级标题============== 二级标题---------------- ...

  6. 2016-2017 ACM Central Region of Russia Quarterfinal Programming Contest BHanoi tower

    B Hanoi tower It has become a good tradition to solve the “Hanoi tower” puzzle at programming contes ...

  7. jQuery 样式操作、文档操作、属性操作的方法总结

    文档操作: addClass()             向匹配的元素添加指定的类名.after()                    在匹配的元素之后插入内容.append()         ...

  8. 编译安装solr

    1, 获取安装包 wget http://download.oracle.com/otn-pub/java/jdk/8u112-b15/jdk-8u112-linux-x64.rpm wget htt ...

  9. 高并发下的HashMap,ConcurrentHashMap

    参照: http://mp.weixin.qq.com/s/dzNq50zBQ4iDrOAhM4a70A http://mp.weixin.qq.com/s/1yWSfdz0j-PprGkDgOomh ...

  10. 设计模式(一)单例模式:3-静态内部类模式(Holder)

    思想: 相比于懒汉以及饿汉模式,静态内部类模式(一般也被称为 Holder)是许多人推荐的一种单例的实现方式,因为相比懒汉模式,它用更少的代码量达到了延迟加载的目的. 顾名思义,这种模式使用了一个私有 ...