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. selenium非常好的资料收集

    非常全的中文资料:http://qi-ling2006.iteye.com/ http://blog.csdn.net/qq744746842/article/details/49926917

  2. Apache Log4j 2 is Coming

    刚刚从同事那里得知,log4j 2 出beta版本了. 有啥提升呢? Improved PerformanceLog4j 2 contains next-generation Asynchronous ...

  3. 编译安装solr

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

  4. javascript学习笔记 - 引用类型 Array

    二 Array 1.可以通过length属性删除或创建新的数组项 arr = [1,2,3]; arr.length = 4;//增加 [1,2,3,undefined] arr.length = 2 ...

  5. 面向对象编程(四)继承,概念及super关键字,final关键字,Object类常见方法

    继承 概念: ①   继承背后的思想就是基于已存在的类来构建新类; ②   当从已存在类继承时,就重用了它的方法和属性,还可以添加新的方法和属性来定制新类以应对需求; ③   当从其它类导出的类叫作子 ...

  6. 【转】深入JVM系列(一)之内存模型与内存分配

    http://lovnet.iteye.com/blog/1825324 一.JVM内存区域划分   大多数 JVM 将内存区域划分为 Method Area(Non-Heap),Heap,Progr ...

  7. kmp-模板-hd-1711

    p数组记录的是当该位置上失配的时候,跳到第几个进行继续匹配: /* 题意:给两个数串,求模板串第一此出现在源串中的位置,开头的位置:没有输出-1: 算法:kmp 先对字符串进行自匹配: 然后串间匹配: ...

  8. [luoguP1129] [ZJOI2007]矩阵游戏(二分图最大匹配)

    传送门 每一行的1和每一列的1不管怎么换还是在同一行和同一列 目标状态中有n个1是不同行且不同列的 那么就是能否找出n个不同行不同列的1 就是每一行选一个不同列的1 如果矩阵中位置i,j为1,那么点i ...

  9. UVA11367 Full Tank? 【分层图最短路】

    题目 After going through the receipts from your car trip through Europe this summer, you realised that ...

  10. 刷题总结——运输计划(bzoj4326)

    题目: 题目背景 NOIP2015 提高组 Day2 T3 题目描述 公元2044年,人类进入了宇宙纪元. L国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n-1 条航道 ...