`

Servlet3.0新特性之异步请求实践

    博客分类:
  • J2EE
 
阅读更多

 

1、为什么要使用异步Servlet?

 

非常适用于以下情况的Web应用程序

 

—— 长处理时间或者伪长处理时间

—— 等待资源释放——如数据库连接

—— 等待事件发生——如聊天消息

—— 等待缓慢服务的响应——如Web服务

 

释放当前请求处理以便处理其他请求

—— 为Web容器提供了更好的可伸缩性

 

浏览器将仍然显示为等待中

—— 用户体验没有改变

 

不要与异步I/O混淆

——目前的Servlet3.0不支持

 

2、AsyncContext 基本知识

 

调用HttpServletRequest.startAsync()将servlet置于异步模式

 

—— 流将不在从Servlet.service()返回时提交

—— 返回AsyncContext对象

 

AsyncContext.start()启动请求

 

—— 将其指派给工作线程

 

AsyncContext.dispatch()

—— 通知工作已经完成

—— 将控件传递回Web容器

 

在以前的Servlet规范化,如果Servlet作为控制器调用了一个耗时的业务方法,那么必须等到业务方法完全返回之后才能生成响应,这将使用Servlet对业务方法的调用变成一种阻塞式的调用,因此效率比较低。

Servlet3.0规范引入了异步处理来解决这个问题,异步处理允许Servlet重新发起一条新线程去调用 耗时业务方法,这样就可以避免等待。

Servlet3.0的异步处理是通过AsyncContext类来处理的,Servlet可通过ServletRequest的如下两个方法开启异步调用,创建AsyncContext对象:

AsyncContext startAsync()

AsyncContext startAsync(ServletRequest,ServletResponse)

 

3、Servlet3.0异步请求实例

 

这个例子只有2文件,一个Servlet和一个Jsp,代码如下:

AsynServlet.java

 

package org.test;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 
 * @ClassName: AsynServlet  
 * @description: 使用批注的方式,指定这个Servlet的映射URL,后面那个配置是设置其是支持异步请求
 * 
 * 1、其它创建一个异步请求和我们平常使用Servlet没什么区别,当然Filter也可以设置为异步的。
 * 2、但是在使用异步请求,我们需要注意一些东西:
 * 1)异步请求完成后指定向的JSP页面,session必须设定为false
 * 2)AsyncListener监听中监听开始在实际无效
 * 3)如果存在过滤器过滤该Servlet,则必须把Filter也要设置为asyncSupported=true,否则会出现异常,提示不支持异步
 *  
 * @createDate: 2013-5-30 下午4:59:31
 * @author linyaoliang 
 * @version
 */
@WebServlet(urlPatterns="/async",asyncSupported=true)
public class AsynServlet extends HttpServlet
{

    private static final long serialVersionUID = 5419388337018572479L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
    {
        resp.setContentType("text/html;charset=GBK");
        PrintWriter out = resp.getWriter();
        out.println("<title>异步调用示例</title>");
        out.println("进入Servlet的时间:"+new java.util.Date()+".<br>");
        out.flush();
        if(req.getAsyncContext() != null)
        {
            System.out.println("异步上下文已经存在");
        }
        //创建AsyncContext,开始异步调用
        AsyncContext actx = req.startAsync();
        actx.addListener(new MyAsyncListener());
        //设置异步调用的超时时长
        actx.setTimeout(30*1000);
        //异步请求上下文启动异步处理线程
        actx.start(new Executor(actx));
        //启动后,输出结束时间
        out.println("结束Servlet的时间:"+new java.util.Date()+".<br>");
        out.flush();
    }

    /**
     * 
     * @ClassName: Executor  
     * @description: 这个是异步请求需要启动来处理长时间业务的线程  
     * @createDate: 2013-5-30 下午4:56:55
     * @author linyaoliang 
     * @version AsynServlet
     */
    class Executor implements Runnable{

        private AsyncContext actx = null;
        
        public Executor(AsyncContext actx)
        {
            this.actx = actx;
        }

        @Override
        public void run()
        {
            try
            {
                System.out.println("====================");
                Thread.sleep(5*1000);
                ServletRequest request = actx.getRequest();
                List<String> books = new ArrayList<String>();
                books.add("Java Programer");
                books.add("Strut Spring hibernate");
                books.add("Test Action");
                request.setAttribute("books", books);
                System.out.println("||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||");
                //当该线程完成后,则返回指定的到这个JSP页面,这个JSP页面必须指定session="false",在这个JSP页面里你可以看到
                actx.dispatch("/async.jsp");
            }
            catch (InterruptedException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
    }
    /**
     * 
     * @ClassName: MyAsyncListener  
     * @description: 异步请求提供的监听  
     * @createDate: 2013-5-30 下午4:54:58
     * @author linyaoliang 
     * @version AsynServlet
     */
    class MyAsyncListener implements AsyncListener
    {

        @Override
        public void onComplete(AsyncEvent arg0) throws IOException
        {
           System.out.println("异步请求已经完成:"+arg0.getAsyncContext().getTimeout());
        }

        @Override
        public void onError(AsyncEvent arg0) throws IOException
        {
            System.out.println("异步请求出错了:"+arg0.getAsyncContext().getTimeout());
        }

        @Override
        public void onStartAsync(AsyncEvent arg0) throws IOException
        {
            //虽然提供了这个监听方法,但是实际没用,因为都是在已经启动异步请求后,得到AsynContext,再去绑定这个监听,可以在上面的代码中看到
            System.out.println("异步请求已经开始:"+arg0.getAsyncContext().getTimeout());
        }

        @Override
        public void onTimeout(AsyncEvent arg0) throws IOException
        {
            System.out.println("异步请求已经超时:"+arg0.getAsyncContext().getTimeout());
        }

    }
}

 

 

async.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8" session="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>异步响应的消息</title>
</head>
<body>
<ul>
	<c:forEach items="${books }" var="book">
		<li>${book }</li>
	</c:forEach>
</ul>
<%out.println("业务调用结束时间:"+new java.util.Date()); %>
</body>
</html>

 

 

分享到:
评论

相关推荐

    Spring Boot实现异步请求(Servlet 3.0)

    在spring 3.2 及以后版本中增加了对请求的异步处理,这篇文章主要介绍了Spring Boot实现异步请求(Servlet 3.0),感兴趣的小伙伴们可以参考一下。

    annotaction

    Servlet 3.0 作为 Java EE 6 规范体系中一员,随着 Java EE 6 规范一起发布。...下面我们将逐一讲解这些新特性,通过下面的学习,读者将能够明晰了解 Servlet 3.0 的变化,并能够顺利使用它 进行日常的开发工作

    看透springMvc源代码分析与实践

    22.1.1 Servlet 3.0处理异步请求实例282 22.1.2 异步请求监听器Async-Listener284 22.2 Spring MVC中的异步请求286 22.2.1 Spring MVC中异步请求相关组件286 22.2.2 Spring MVC对异步请求的支持297 22.2.3 ...

    Java™ Servlet 规范.

    1.4 Servlet 与其他技术的比较 ........................................................................................................................14 1.5 与 Java 平台企业版的关系 ......................

    Web服务请求异步化测试

     Web服务异步化: 包括两部分,数据传输层异步化(大家已经熟知的NIO),Http业务请求异步化(continuations,servlet3.0)。服务异步处理我将会有一个详细的说明文档(服务异步化的概念,服务异步化的几种标准实现,...

    基于 servlet 开发的学生管理系统(mvc+bootstrap+jquery3.0+mysql)

    2.前 HTMl+css+javascipt,框架是 Bootstrap4.0,Jquery3.2 表单验证,异步请求、 3.数据库 Mysql 以及 Druid 连接池、服务器使用 Tomact8.5,开发工具 Idea2018、 4. 结构上分为表现层、业务层和数据访问层,层次间的...

    servlet3-filter-async-test

    异步模式下的过滤器链(servlet 规范 3.0+)在 servlet 规范中似乎受到严重限制(整个过滤器-servlet 处理链必须在同一线程中运行)并且并不总是完全清楚先前存在的 API 表面的哪些部分是指与异步功能( )互操作。...

    Tomcat 8 软件及源码

    5. JSP 2.3支持:Tomcat 8 支持最新的JSP 2.3规范,包括对新特性和改进的支持,如EL 3.0、标签文件的静态引入等。 6. HTTP/2支持:Tomcat 8 支持HTTP/2协议,可以提供更快的页面加载速度和更高的性能。 7. NIO2支持...

    tomcat-8.0.21

    Tomcat8新版本特性: 1.支持servlet3.1, jsp 2.3, el表达式3.0 and Java WebSocket 1.0. 2.默认http与ajp请求实现non-blocking技术,即NIO技术。 3.多个应用发布的时候可以先打成jar包,然后打成一个总的war发布。...

    未过滤:用于在Scala中处理HTTP请求的工具包

    过滤将核心库绑定到Servlet 3.0 API中的过滤器。过滤异步为过滤器模块提供异步支持码头提供用于服务过滤器的嵌入式Web服务器抽象。净值将核心库绑定到Netty通道处理程序,并提供嵌入式服务器。净负荷为使用netty的多...

    通俗易懂的Spring注解驱动开发教程(含配套资料)

    本教程为授权出品教程 《Spring注解驱动开发》是一套帮助我们深入了解Spring原理... 3).web原理 1).Servlet3.0标准新增特性 2).异步请求相关 本视频使用了maven构建程序,需要同学们有对Spring.SpringMVC的基本

    Servlet3.1规范(最终版) PDF

    Servlet3.1规范(最终版) JavaTM Servlet 规范 版本 3.1(最终版) Shing Wai Chan Rajiv Mordani [作者] 穆茂强 张开涛 [译者] 2012年6月翻译 2013年7月修订 目录 前言 ............................... 3 ...

    apache-tomcat-8.0.0-RC5

    支持servlet3.1, jsp 2.3, el表达式3.0 and Java WebSocket 1.0. 2.默认http与ajp请求实现non-blocking技术,即NIO技术。 3.多个应用发布的时候可以先打成jar包,然后打成一个总的war发布。(这句翻译不太准,意思...

    shiro-guice-async-webapp:使用 Apache Shiro 1.2.3、JBoss RestEasy 3 和 Google Guice 3 的 RESTful Web 服务,支持异步 HTTP 请求处理

    包含的依赖项Servlet 3.1.0 ( ) JBoss RestEasy 3.0.9.Final ( ) Guice 3.0 ( ) Apache Shiro 1.2.3 ( ) gson 2.2.4 ( ) 乔达时间 2.4 ( ) JUnit 4.10 ( ) Jukito 1.4 ( ) Logback + SLF4J XLogger ( )要求Java 8 ...

    Ajax技术课件,保密资料下载

    1 异步请求对象 xhr javascript对象 ---- 浏览器中 ---- 浏览器差异 window.XMLHttpRequest window.ActiveXObject Firefox XMLHttpRequest var xhr = new XMLHttpRequest(); IE ActiveXObject ...

    spring-async

    该项目的目的是展示Servlet 3.0规范中添加的Async功能。 该API仅具有带有POST方法的Controller。 资源的名称是/ operation。 要进行新操作,需要使用以下Json进行新的POST请求: {“ id”:“ 3”,“ firstOperand...

    开涛高可用高并发-亿级流量核心技术

    3.11.5 一些Servlet 3异步化压测数据 64 4 限流详解 66 4.1 限流算法 67 4.1.1 令牌桶算法 67 4.1.2 漏桶算法 68 4.2 应用级限流 69 4.2.1 限流总并发/连接/请求数 69 4.2.2 限流总资源数 70 4.2.3 限流某个接口的总...

    Spring.3.x企业应用开发实战(完整版).part2

     Spring3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架、REST风格的Web编程模型等。这些新功能实用性强、易用性高,可大幅降低Java应用,特别是JavaWeb应用开发的难度,同时有效提升...

    Spring3.x企业应用开发实战(完整版) part1

     Spring3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架、REST风格的Web编程模型等。这些新功能实用性强、易用性高,可大幅降低Java应用,特别是JavaWeb应用开发的难度,同时有效提升...

    整理后java开发全套达内学习笔记(含练习)

    abstract (关键字) 抽象 ['æbstrækt] access vt.访问,存取 ['ækses]'(n.入口,使用权) algorithm n....Annotation [java] 代码注释 [ænәu'teiʃәn] anonymous adj.匿名的[ә'nɒnimәs]'(反义:directly adv....

Global site tag (gtag.js) - Google Analytics