【web.xml】

<filter>
<filter-name>normalFilter</filter-name>
<filter-class>net.mypla.controller.filter.AnyRequestFilter</filter-class>
<async-supported>true</async-supported> <!--请求启动AsyncContext必要声明-->
</filter> <filter-mapping>
<filter-name>normalFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher><!--只拦截普通请求-->
</filter-mapping> <filter>
<filter-name>forwardFilter</filter-name>
<filter-class>net.mypla.controller.filter.AnyRequestFilter</filter-class>
<async-supported>true</async-supported>
</filter> <filter-mapping>
<filter-name>forwardFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher><!--只拦截转发请求-->
</filter-mapping> <filter>
<filter-name>asyncFilter</filter-name>
<filter-class>net.mypla.controller.filter.AnyRequestFilter</filter-class>
<async-supported>true</async-supported>
</filter> <filter-mapping>
<filter-name>asyncFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>ASYNC</dispatcher><!--拦截由AsyncContext派发的请求-->
</filter-mapping> 【AnyRequestFilter】
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException {
System.out.println("Entering " + this.name + ".doFilter().");
filterChain.doFilter(new HttpServletRequestWrapper((HttpServletRequest) req), new HttpServletResponseWrapper((HttpServletResponse) resp));
//真正处理async请求
if (req.isAsyncSupported() && req.isAsyncStarted()) {
AsyncContext context = req.getAsyncContext();
System.out.println("Leaving " + this.name + ".doFilter(),async" +
"context holds wrapped req/resp = " +
!context.hasOriginalRequestAndResponse());
} else {
System.out.println("leaving " + this.name + ".doFilter().");
}
}
【异步Servlet】异步请求,关键代码
//过滤器有wrap这个动作,我们有收到unwrap的话就是不要wrap
//unwrap 原始参数启动异步 、 没有unwrap就用wrap后的req resp
final AsyncContext context = req.getParameter("unwrap")!=null?
req.startAsync():req.startAsync(req,resp);
//timeout 是请求参数 ?timeout=10000
context.setTimeout(timeout); System.out.println("Starting asynchronous thread.Request ID = "+id+"."); AsyncThread thread = new AsyncThread(id,context);
context.start(thread::doWork);
【异步线程】启动一个线程去处理,最终采用异步派发 而不是直接处理
public void doWork(){
System.out.println("Asynchronous thread started. Request ID = "+
this.id+".");
//当前线程休眠5秒
try {
Thread.sleep(5_000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
  //异步请求
HttpServletRequest request = (HttpServletRequest) this.context.getRequest();
System.out.println("Done sleeping. Request ID = "+this.id+
",URL="+request.getRequestURL()+".");
this.context.dispatch("/WEB-INF/jsp/filter/async.jsp");//异步派发,过滤器拦截。(如果AsyncContext直接处理掉请求,过滤器无法拦截。)
System.out.println("Asynchronous thread completed. Request ID = "+
this.id+".");
}
												

Filter 快速开始 异步Servlet 异步请求 AsyncContext 异步线程 异步派发 过滤器拦截的更多相关文章

  1. Servlet 3特性:异步Servlet

    解异步Servlet之前,让我们试着理解为什么需要它.假设我们有一个Servlet需要很多的时间来处理,类似下面的内容: LongRunningServlet.java package com.jou ...

  2. 使用tomcat7创建异步servlet

    该篇文章翻译自:http://developerlife.com/tutorials/?p=1437 一.简介 Servlet API 3.0 之前,需要使用类似Comet的方式来实现创建异步的Ser ...

  3. 异步Servlet的理解与实践

    AsyncContext理解 Servlet 3.0(JSR315)定义了Servlet/Filter的异步特性规范. 怎么理解"异步Servlet/Filter"及其使用情景? ...

  4. 异步Servlet和异步过虑器

    异步处理功能可以节约容器线程.此功能的作用是释放正在等待完成的线程,是该线程能够被另一请求所使用. 要编写支持异步处理的 Servlet 或者过虑器,需要设置 asyncSupported 属性为 t ...

  5. 关于servlet3.0中的异步servlet

    刚看了一下维基百科上的介绍,servlet3.0是2009年随着JavaEE6.0发布的: 到现在已经有六七年的时间了,在我第一次接触java的时候(2011年),servlet3.0就已经出现很久了 ...

  6. WebFlux01 webflux概念、异步servlet、WebFlux意义

    1 概念 待更新...... 2 异步servlet 2.1 同步servlet servlet容器(如tomcat)里面,每处理一个请求会占用一个线程,同步servlet里面,业务代码处理多久,se ...

  7. 异步servlet的原理探究

    异步servlet是servlet3.0开始支持的,对于单次访问来讲,同步的servlet相比异步的servlet在响应时长上并不会带来变化(这也是常见的误区之一),但对于高并发的服务而言异步serv ...

  8. Spring Boot异步发送邮件和请求拦截器配置

    用户登录流程图: 在spring拦截器中进行鉴权操作: 控制器的拦截: import com.mooc.house.common.model.User; import org.springframew ...

  9. 使用HttpClient来异步发送POST请求并解析GZIP回应

    .NET 4.5(C#): 使用HttpClient来异步发送POST请求并解析GZIP回应 在新的C# 5.0和.NET 4.5环境下,微软为C#加入了async/await,同时还加入新的Syst ...

随机推荐

  1. iptables防火墙详解(三)

    linux 高级路由 策略路由(mangle表) lartc(linux advanced routing and traffic control) http://www.lartc.org # rp ...

  2. Weblate 2.11安装配置文档

    一.系统环境: OS:CentOS 6.8 x64 Minimal HostName:Weblate IP:192.168.75.153 Python:2.7.13 pip:9.0.1 Weblate ...

  3. Dockerfile技巧

    换镜像源 Ubuntu RUN sed -i 's/archive.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list A ...

  4. Nodejs nmp 常用命令

    npm是一个node包管理和分发工具,已经成为了非官方的发布node模块(包)的标准.有了npm,可以很快的找到特定服务要使用的包,进行下载.安装以及管理已经安装的包. 1.npm install m ...

  5. 基于tensorflow的MNIST手写数字识别(二)--入门篇

    http://www.jianshu.com/p/4195577585e6 基于tensorflow的MNIST手写字识别(一)--白话卷积神经网络模型 基于tensorflow的MNIST手写数字识 ...

  6. java的抽象方法

    抽象类所起的功能就像定义模板的功能,子类必须继承抽象类,因此不能用final修饰 http://blog.csdn.net/wei_zhi/article/details/52736350 抽象类的函 ...

  7. hdu 3530 "Subsequence" (单调队列)

    传送门 题意: 给出一个序列,求最长的连续子序列,使得 m ≤ Max-Min ≤ k 我的理解: 定义数组 a[] 存储输入的 n 个数: 定义两个双端队列: deque<int >qM ...

  8. 数据库事务的隔离以及spring的事务传播机制

    数据库的事务隔离: MySQL InnoDB事务的隔离级别有四级,默认是“可重复读”RR(REPEATABLE READ). oracle默认的是提交读.RC 未提交读(READ UNCOMMITTE ...

  9. node.js(基础四)_express基础

    一.前言                                                           本次内容主要包括: 1.express的基本用法 2.express中的静 ...

  10. Altium Designer 18 ------ 常用功能记录

    PCB选中某条线路,按一下 Tab 键选中整条线路 PCB中,按 “N” 键选择隐藏或显示某个网络 配置Altium Designer 18 教程所需的捕捉网格的值: G显示Snap Grid菜单,您 ...