servlet之前的操作同时同步的,就是按照这样的一个流程来走的:

1.请求根据一个路径路由到一个servlet中,

2.servlet获取一系列的参数

3.执行一系列的逻辑(花费时间所占的比重也更大)

4.返回结果

上面的问题出现在这一系列的操作都是同步的,所以这个请求必定是堵塞到所以任务都完成之后才返回的,

这样将会很浪费资源,因为线程堵塞在那里,仅仅是等待任务的完成。但是在servlet3.0之后,我们基本上可以

是这样做的

1.请求根据一个路径路由到一个servlet中,

2.将逻辑放入到异步队列中去

3.返回结果

4.异步队列处理任务,得出结果,返回给页面

而servet3.0对于异步的处理主要涉及的有两个特性,一个是新增的类AsyncContext,另外的一个就是asyncSupported属性

①如果我们想要让我们的servlet支持异步的话,那么asyncSupported这个属性是一定需要设置的,对于注解的类型来说,我们直接设置属性

@WebServlet(asyncSupported=true,urlPatterns={"/async"})

就可以了,对于老版本的配置问价来说,只需要在配置web.xml 的servlet那里增加一个

<async-supported>true</async-supported> 
②而对于AsyncContext 需要记住的东西还是蛮多的,但是它主要的是保留了请求和相应的引用,在前面提到的返回结果之后的操作就是通过在异步环境下,对这两个引用进行操作。

要获取这个就需要使用request在3.0之后增加的方法,startAsync(..) ,这个方法就是返回一个AsyncContext实体对象,这里包含了request和response的引用,直接使用AsyncContext.start(Runnable)方法启动一个新的线程去进行处理逻辑
AsyncContext主要的方法:
getRequest() 获得请求即request,我们可以在异步的环境像在service中使用一样

getReponse() 和上面差不多一个意思

hasOriginalRequestAndResponse()这个方法表示的是我们使用的AsyncContext是使用原始的请求获取的,还是通过封装过的请求和相应创建的
简单的讲就是 原始的类型表示的是调用startAsync()。但是封装的就是startAsync(ServletRequest, ServletResponse)或者其他类型啦,

dispatch()方法,这个方法有有好几个重载,表示的是转发,和req.getRequestDispatcher()有点类似,但是比较丰富
如果使用的是startAsync(ServletRequest, ServletResponse)初始化AsyncContext,且传入的请求是HttpServletRequest的一个实例,则使用HttpServletRequest.getRequestURI()返回的URI进行分派。否则分派的是容器最后分派的请求URI。
下面的代码是网上的:dispatch(String path) 这个方法就是转发到指定的url上去
// 请求到 /url/A
AsyncContext ac = request.startAsync();
...
ac.dispatch(); // 异步分派到 /url/A // 请求到 /url/A
// 转发到 /url/B
request.getRequestDispatcher(“/url/B”).forward(request, response);
// 从FORWARD的目标内启动异步操作
AsyncContext ac = request.startAsync();
ac.dispatch(); // 异步分派到 /url/A // 请求到 /url/A
// 转发到 /url/B
request.getRequestDispatcher(“/url/B”).forward(request, response);
// 从FORWARD的目标内启动异步操作
AsyncContext ac = request.startAsync(request, response);
ac.dispatch(); //异步分派到 /url/B

complete():在我们使用了request.startAsync(..)获得AsyncContext之后,在完成异步操作以后,需要调用这个方法结束异步的操作。如果请求分派到一个不支持异步操作的Servlet,或者由AsyncContext.dispatch调用的目标servlet之后没有调用complete,则complete方法会由容器调用。

setTimeOut(..) 设置超时的时间 表示的是异步处理的最大时间,如果是一个负数的话,那么表示永远不会超时

start(Runnable run) Runnable表示的就是异步处理的任务。我们在做的时候 会AsyncContext  带进去 因为所以的操作 都需要依靠他呢

addListener(AsyncListener listener);增加监听器  就是监听AsyncContext各种状态发现变化的,主要有

前面三个都比较好理解,最后异步监听器将以它们添加到请求时的顺序得到通知。

下面是AsyncContext的一般使用方式

1. 模拟注册发信息到邮件的简单的异步处理 Servlet 示例代码:

package com.servlet;

import java.io.IOException;

import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; @WebServlet(value="/asyn-servlet",asyncSupported=true)
public class ServletAsyn extends HttpServlet {
private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("Servlet is start"); //1.获得异步上下文对象
AsyncContext ac = request.startAsync();
//2.启动一个耗时的子线程
ThreadTask tt = new ThreadTask(ac);
//3.可设置异步超时对象,需在启动异步上下文对象前设置
/*
* 设置超时后,在超时时间内子线程没有结束,主线程则会停止等待,继续往下执行
*/
ac.setTimeout(3000);
//4.开启异步上下文对象
ac.start(tt); //主线程结束向客户端发送消息
System.out.println("Servlet is end");
response.setContentType("text/html;charset=utf-8");
response.getWriter().append("信息已发送到邮箱");
} protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
} }

异步线程的执行类:

package com.servlet;

import java.util.Date;

import javax.servlet.AsyncContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession; public class ThreadTask implements Runnable{
private AsyncContext ac; //定义一个异步上下文 public ThreadTask(AsyncContext ac) {
super();
this.ac = ac;
} @Override
public void run() {
/*
* 服务端异步典型应用是注册时向邮箱发送验证码
*/
try {
//进行异步的一些处理
HttpServletRequest requst = (HttpServletRequest) ac.getRequest();
HttpSession session = requst.getSession();
System.out.println("asyn-task start" + new Date());
for(int i=5;i>0; i--) {
System.out.println(i);
Thread.sleep(1000);
}
//将结果放到session等方式
session.setAttribute("message", "This is the result of asyn");
System.out.println("asyn-task end" + new Date()); //通知主线程已经处理完成
/*
* 除了使用 ac.complete() 方法通知主线程已经处理外
* 还可以使用 ac.dispatch() 方法重定向到一个页面
*/
ac.dispatch("/show.jsp");
} catch (Exception e) {
e.printStackTrace();
}
} }

十三:Servlet3.0的异步的更多相关文章

  1. Servlet3.0的异步

    servlet之前的操作同时同步的,就是按照这样的一个流程来走的: 1.请求根据一个路径路由到一个servlet中, 2.servlet获取一系列的参数 3.执行一系列的逻辑(花费时间所占的比重也更大 ...

  2. Servlet3.0对异步处理的支持

    Servlet工作流程 Servlet 3.0 之前,一个普通 Servlet 的主要工作流程大致如下: Servlet 接收到请求之后,可能需要对请求携带的数据进行一些预处理: 调用业务接口的某些方 ...

  3. Filter学习总结,顺便提及点servlet3.0异步filter和异步监听

      Filter介绍:     Filter在项目中经常可以用到,通常配置在web.xml中.是服务器端的一个组件,对于用户的请求和响应数据进行过滤操作,控制是否让用户访问到对应的web资源.常用于编 ...

  4. 深入理解Servlet3.0异步请求

    异步请求的基础概念 异步请求最直接的用法就是处理耗时业务,Http协议是单向的,只能客户端拉不能服务器主推. 异步请求的核心原理主要分为两大类:1.轮询.2长连接 轮询:就是定时获取返回结果. 长连接 ...

  5. Servlet3.0的新特性

    注意:Servlet3.0的项目一定要使用Tomcat7.0才能看到效果!! 1.新增标注支持     在Servlet3.0的部署描述文件web.xml的顶层标签<web-app>中有一 ...

  6. Servlet3.0新特性使用详解

    可插拔的Web框架 几乎所有基于Java的web框架都建立在servlet之上.现今大多数web框架要么通过servlet.要么通过Web.xml插入.利用标注(Annotation)来定义servl ...

  7. Servlet3.0新特性(从注解配置到websocket编程)

    Servlet3.0的出现是servlet史上最大的变革,其中的许多新特性大大的简化了web应用的开发,为广大劳苦的程序员减轻了压力,提高了web开发的效率.主要新特性有以下几个: 引入注解配置 支持 ...

  8. Servlet 3.0 对异步处理的支持

    Servlet 3.0 实现了对异步处理的支持 通过利用注解@WebServlet(urlPatterns="/AServlet" AysnsSupported=true) 让后n ...

  9. Servlet3.0 新特性

    Servlet3.0 的注解 Servlet 允许开发人员采用注解的方式来配置 Servlet.Filter.Listener. Servlet3.0 规范在 javax.servlet.annota ...

随机推荐

  1. AcWing 1086. 恨7不成妻(【代码简洁】标准记忆化搜索+超详解!!)

    看到这题用循环写的dp代码瑟瑟发抖~ 数位dp一般记忆化搜索的写法思维难度较低,也比较常用,这题的简洁代码应该就可以显现出其优越性 (用时4ms,可能比用循环写的dp还要快) 那这里补充一下记忆化搜索 ...

  2. linux U盘安装系统工具usb-creator-gtk

    linux平台下U盘安装linux系统的工具.它是ubuntu自带的工具,将建时将覆盖U盘中的所有内容.

  3. 微信小程序云开发-云存储-下载并打开文件文件(word/excel/ppt/pdf)

    一.wxml文件 1.写文本框,用来获取文件链接. 2.按钮,点击下载文件 <!-- 下载文件(word/excel/ppt/pdf等) --> <view class=" ...

  4. MySQL中的redo log和undo log

    MySQL中的redo log和undo log MySQL日志系统中最重要的日志为重做日志redo log和归档日志bin log,后者为MySQL Server层的日志,前者为InnoDB存储引擎 ...

  5. Spring 学习笔记(2) Spring Bean

    一.IoC 容器 IoC 容器是 Spring 的核心,Spring 通过 IoC 容器来管理对象的实例化和初始化(这些对象就是 Spring Bean),以及对象从创建到销毁的整个生命周期.也就是管 ...

  6. Python 机器学习实战 —— 无监督学习(上)

    前言 在上篇<Python 机器学习实战 -- 监督学习>介绍了 支持向量机.k近邻.朴素贝叶斯分类 .决策树.决策树集成等多种模型,这篇文章将为大家介绍一下无监督学习的使用.无监督学习顾 ...

  7. 自建CA实现HTTPS

    说明:这里是Linux服务综合搭建文章的一部分,本文可以作为自建CA搭建https网站的参考. 注意:这里所有的标题都是根据主要的文章(Linux基础服务搭建综合)的顺序来做的. 如果需要查看相关软件 ...

  8. 流畅的python--函数

    # # -*- coding: utf-8 -*-#from abc import ABC ,abstractclassmethodfrom collections import namedtuple ...

  9. odoo里面的一些ORM操作

    案例0001sale_obj=self.env['sale.order'].browse(k)通过browse查找对象找到对象里面的 sale_obj.name browse 获取一个数据库id或一个 ...

  10. 【阿菜用工具】Slither:Solidity静态分析框架

    工具简介 Slither 是一个 python3 开发,用于检测智能合约(solidity)漏洞的静态分析框架. Slither 的 Github 地址:https://github.com/cryt ...