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 ...
随机推荐
- 《java入门第一季》之面向对象(修饰符的概念和总结)
还是由于eclipde等ide的强大功能,会自动提示你修饰符是否可行.所以对修饰符的作用了解即可: 修饰符: 权限修饰符:private,默认的,protected,public ...
- MySQL正则表达式初步
如果想要了解完整的MySQL手册, 请访问: MySQL 5.1参考手册 你还可以学习: MySQL学习精粹 我们知道,在SQL之中,可以用 like 这个谓词(表达式) 来进行模糊检索,并支持 %, ...
- Android免Root无侵入AOP框架Dexposed
Dexposed框架是阿里巴巴无线事业部近期开源的一款在Android平台下的免Root无侵入运行期AOP框架,该框架基于AOP思想,支持经典的AOP使用场景,可应用于日志记录,性能统计,安全控制,事 ...
- 【Android 应用开发】AndroidUI设计 之 图片浏览器
图片浏览器效果图 : 源码下载地址 : -- CSDN : http://download.csdn.net/detail/han1202012/6875083 -- GitHub : https:/ ...
- 让App中加入LruCache缓存,轻松解决图片过多造成的OOM
上次有过电话面试中问到Android中的缓存策略,当时模糊不清的回答,现在好好理一下吧. Android中一般情况下采取的缓存策略是使用二级缓存,即内存缓存+硬盘缓存->LruCache+Dis ...
- TCP的核心系列 — SACK和DSACK的实现(七)
我们发送重传包时,重传包也可能丢失,如果没有检查重传包是否丢失的机制,那么只能依靠超时来恢复了. 37版本把检查重传包是否丢失的部分独立出来,这就是tcp_mark_lost_retrans(). 在 ...
- Mina源码阅读笔记(六)—Mina异步IO的实现IoFuture
IoFuture是和IoSession紧密相连的一个类,在官网上并没有对它的描述,因为它一般不会显示的拿出来用,权当是一个工具类被session所使用.当然在作用上,这个系列可并不简单,我们先看源码的 ...
- LeetCode(31)-Factorial Trailing Zeroes
题目: Given an integer n, return the number of trailing zeroes in n!. Note: Your solution should be in ...
- java 如何使的float保留2位或者多位小数 (转载)
转载自 http://blog.csdn.net/com_stu_zhang/article/details/7214565 方法1: float f = 34.232323; Big ...
- xmlrpc
xmlrpc编辑 官方URL:http://ws.apache.org/xmlrpc/xmlrpc2/index.html 本词条缺少名片图,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧! x ...