servlet3.0 新特性——异步处理
Servlet 3.0 之前,一个普通 Servlet 的主要工作流程大致如下:
首先,Servlet 接收到请求之后,可能需要对请求携带的数据进行一些预处理;
接着,调用业务接口的某些方法,以完成业务处理;
最后,根据处理的结果提交响应,Servlet 线程结束。
其中第二步的业务处理通常是最耗时的,这主要体现在数据库操作,以及其它的跨网络调用等,在此过程中,Servlet 线程一直处于阻塞状态,直到业务方法执行完毕。在处理业务的过程中,Servlet 资源一直被占用而得不到释放,对于并发较大的应用,这有可能造成性能的瓶颈。即使在业务类中开启一个线程,线程处理后的结果是无法返回给页面的,因为servlet执行完毕后,response就关闭了,无法将后台更新数据即时更新到页面端
注:servlet3.0 以前通常是采用私有解决方案来提前结束 Servlet 线程,并及时释放资源。
Servlet 3.0 针对这个问题做了开创性的工作,现在通过使用 Servlet 3.0 的异步处理支持,之前的 Servlet 处理流程可以调整为如下的过程:
首先,Servlet 接收到请求之后,可能首先需要对请求携带的数据进行一些预处理;
接着,Servlet 线程将请求转交给一个异步线程来执行业务处理,线程本身返回至容器,此时 Servlet 还没有生成响应数据,异步线程处理完业务以后,可以直接生成响应数据(异步线程拥有 ServletRequest 和 ServletResponse 对象的引用),或者将请求继续转发给其它 Servlet。
如此一来, Servlet 线程不再是一直处于阻塞状态以等待业务逻辑的处理,而是启动异步线程之后可以立即返回。
1、异步处理特性可以应用于 Servlet 和过滤器两种组件,由于异步处理的工作模式和普通工作模式在实现上有着本质的区别,因此默认情况下,Servlet 和过滤器并没有开启异步处理特性,如果希望使用该特性,则必须按照如下的方式启用:
- 对于使用传统的部署描述文件 (web.xml) 配置 Servlet 和过滤器的情况,Servlet 3.0 为 <servlet> 和 <filter> 标签增加了 <async-supported> 子标签,该标签的默认取值为 false,要启用异步处理支持,则将其设为 true 即可。以 Servlet 为例,其配置方式如下所示:
<servlet>
<servlet-name>DemoServlet</servlet-name>
<servlet-class>footmark.servlet.Demo Servlet</servlet-class>
<async-supported>true</async-supported>
</servlet> - 对于使用 Servlet 3.0 提供的 @WebServlet 和 @WebFilter 进行 Servlet 或过滤器配置的情况,这两个注解都提供了 asyncSupported 属性,默认该属性的取值为 false,要启用异步处理支持,只需将该属性设置为 true 即可。以 @WebFilter 为例,其配置方式如下所示:
@WebFilter(urlPatterns = "/demo",asyncSupported = true)
public class DemoFilter implements Filter{...}
2、Servlet 3.0 还为异步处理提供了一个监听器,使用 AsyncListener 接口表示。它可以监控如下四种事件:
- 异步线程开始时,调用 AsyncListener 的 onStartAsync(AsyncEvent event) 方法;
- 异步线程出错时,调用 AsyncListener 的 onError(AsyncEvent event) 方法;
- 异步线程执行超时,则调用 AsyncListener 的 onTimeout(AsyncEvent event) 方法;
- 异步执行完毕时,调用 AsyncListener 的 onComplete(AsyncEvent event) 方法;
AsyncContext ctx = req.startAsync();
ctx.addListener(new AsyncListener() {
public void onComplete(AsyncEvent asyncEvent) throws IOException {
// 做一些清理工作或者其他
}
...
});
- package com.darren.servlet;
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.util.Date;
- import javax.servlet.AsyncContext;
- import javax.servlet.AsyncEvent;
- import javax.servlet.AsyncListener;
- import javax.servlet.ServletException;
- import javax.servlet.annotation.WebServlet;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- /**
- * servlet3.0默认是不支持异步的通过asyncSupported=true,打开
- *
- */
- @WebServlet(name="SecondServlet",urlPatterns={"/secondServlet"},asyncSupported=true)
- public class SecondServlet extends HttpServlet {
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException {
- PrintWriter out = null;
- resp.setContentType("text/html");
- try {
- out = resp.getWriter();
- out.print("servlets starts:"+new Date()+"<br>");
- out.flush();
- AsyncContext asyncContext = req.startAsync();
- /**
- * AsyncListener为什么没有适配器呢?需要各个厂家实现?
- */
- asyncContext.addListener(new AsyncListener(){
- public void onComplete(AsyncEvent asyncEvent) throws IOException {
- //将流在这里关闭
- asyncEvent.getSuppliedResponse().getWriter().close();
- System.out.println("asynContext finished....");
- }
- public void onError(AsyncEvent arg0) throws IOException {
- // TODO Auto-generated method stub
- }
- public void onStartAsync(AsyncEvent arg0) throws IOException {
- // TODO Auto-generated method stub
- }
- public void onTimeout(AsyncEvent arg0) throws IOException {
- // TODO Auto-generated method stub
- }
- });
- new Thread(new MyThread(asyncContext)).start();
- out.print("servlets ends:"+new Date()+"<br>");
- out.flush();
- } finally {
- /**
- * 一开是在这里关闭了,关了,后面就用不成了 :)
- *
- */
- /*if(null != out){
- out.close();
- out = null;
- }*/
- }
- }
- }
MyThread.java:
- package com.darren.servlet;
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.util.Date;
- import javax.servlet.AsyncContext;
- public class MyThread implements Runnable {
- private AsyncContext asyncContext;
- public MyThread(AsyncContext asyncContext) {
- this.asyncContext = asyncContext;
- }
- public void run() {
- PrintWriter out = null;
- try {
- try {
- Thread.sleep(10000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- out = asyncContext.getResponse().getWriter();
- out.println("myTask starts:"+new Date()+"<br>");
- out.flush();
- out.print("myTask ends:"+new Date()+"<br>");
- out.flush();
- asyncContext.complete();
- } catch (IOException e) {
- e.printStackTrace();
- }finally{
- /*if(null != out){
- out.close();
- out = null;
- }*/
- }
- }
- }
servlet3.0 新特性——异步处理的更多相关文章
- Servlet3.0新特性
1 Servlet3.0新特性概述 使用要求:MyEclipse10.0或以上版本,发布到Tomcat7.0或以上版本,创建JavaEE6.0应用! Servlete3.0的主要新特性如下三部分: 使 ...
- 【servlet3.0新特性】Annotation注解配置
servlet3.0新特性Servlet3.0引入的若干重要新特性,包括异步处理.新增的注解支持.可插性支持等等,为读者顺利向新版本过渡扫清障碍.Servlet3.0新特性概述Servlet3.0作为 ...
- 使用Servlet3.0新特性asyncSupported=true时抛异常java.lang.IllegalStateException: Not supported
最近在运用Servlet3.0新特性:异步处理功能的时候出现以下了2个问题: 运行时会抛出以下两种异常: 一月 19, 2014 3:07:07 下午 org.apache.catalina.core ...
- Java基础加强-(注解,动态代理,类加载器,servlet3.0新特性)
1. Annotation注解 1.1. Annotation概述 Annotation是JDK 5.0以后提供对元数据的支持,可以在编译.加载和运行时被读取,并执行相应的处理.所谓Annota ...
- 【Servlet3.0新特性】第03节_文件上传
这是一个Web Project 首先是web.xml <?xml version="1.0" encoding="UTF-8"?> <web- ...
- Servlet3.0新特性(从注解配置到websocket编程)
Servlet3.0的出现是servlet史上最大的变革,其中的许多新特性大大的简化了web应用的开发,为广大劳苦的程序员减轻了压力,提高了web开发的效率.主要新特性有以下几个: 引入注解配置 支持 ...
- Servlet3.0新特性使用详解
可插拔的Web框架 几乎所有基于Java的web框架都建立在servlet之上.现今大多数web框架要么通过servlet.要么通过Web.xml插入.利用标注(Annotation)来定义servl ...
- Servlet3.0 新特性
Servlet3.0 的注解 Servlet 允许开发人员采用注解的方式来配置 Servlet.Filter.Listener. Servlet3.0 规范在 javax.servlet.annota ...
- Java自学手记——servlet3.0新特性
servlet3.0出来已经很久了,但市场上尚未普遍应用,servlet3.0有三个比较重要的新特性:使用注解来代替配置文件,异步处理以及上传组件支持. 支持servlet3.0的要求:MyEclip ...
随机推荐
- Android For JNI(四)——C的数组,指针长度,堆内存和栈内存,malloc,学生管理系统
Android For JNI(四)--C的数组,指针长度,堆内存和栈内存,malloc,学生管理系统 好几天每写JNI了,现在任务也越来越重了,工作的强度有点高,还有好几个系列的博客要等着更新,几本 ...
- Android免Root无侵入AOP框架Dexposed
Dexposed框架是阿里巴巴无线事业部近期开源的一款在Android平台下的免Root无侵入运行期AOP框架,该框架基于AOP思想,支持经典的AOP使用场景,可应用于日志记录,性能统计,安全控制,事 ...
- 《java入门第一季》之面向对象(重头戏继承来了)
java特性封装.继承.多态.之前对封装做了简单描述(见http://blog.csdn.net/qq_32059827/article/details/51312116),今天分析另一个特性继承性: ...
- Java的依赖注入(控制反转)
两个主角"依赖注入"和"控制反转": 1.二都说的都是同一件事,只是叫法不同.是一个重要的面向对象编程的法则,也是一种设计模式: 2.英文原称:依赖注入,Dep ...
- RHEL6 安装KVM
RHEL6 安装KVM # egrep '^flags.*(vmx|svm)' /proc/cpuinfo 有显示说明CPU支持VT功能 2.在主板BIOS中开启CPU的Virtual Technol ...
- linux socket编程之TCP与UDP
转:http://blog.csdn.net/gaoxin1076/article/details/7262482 TCP/IP协议叫做传输控制/网际协议,又叫网络通信协议 TCP/IP虽然叫传输控制 ...
- ngnix服务器搭建
1. 到nginx官网上下载相应的安装包,http://nginx.org/en/download.html:下载进行解压,将解压后的文件放到自己心仪的目录下,我的解压文件放在了d盘根目录下,如下图 ...
- Android Xlistview的源码浅度分析 监听ListView上下滑动 以及是否到顶和底部
如转载 请注明出处 http://blog.csdn.net/sk719887916 比如我们很多项目中会用到listview 并且要对listview滑动方向进行判断 也有需要的到listview是 ...
- IOS中用到的缓存
App已经与我们形影不离了,不管在地铁上.公交上还是在会场你总能看到很多人拿出来手机,刷一刷微博,看看新闻. 据不完全统计有近一半的用户在非Wifi环境打开App,以下为一个典型iPhone和Andr ...
- WebService学习--(二)webservice相关介绍
一.WebService是什么? 1. 基于Web的服务:服务器端整出一些资源让客户端应用访问(获取数据) 2. 一个跨语言.跨平台的规范(抽象) 3. 多个跨平台.跨语言的应用间通信整合的方案(实际 ...