Servlet3.0提供的异步处理

    在以前的Servlet规范中,如果Servlet作为控制器调用了一个耗时的业务方法,那么Servlet必须等到业务方法完全返回之后才会生成响应,这将使得Servlet对业务方法的调用变成一种阻塞式的调用,因此效率比较低。Servlet3.0规范引入了异步处理来解决这个问题,异步处理允许Servlet重新发起一条线程去调用耗时的业务方法,这样就可以避免等待。

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

  • AsyncContext startAsync()
  • AsyncContext startAsync(ServletRequest, ServletResponse)

    重复调用上面的方法将得到同一个AsyncContext对象。AsyncContext对象代表异步处理的上下文,它提供了一些工具方法,可完成设置异步调用的超时时长,dispatch用于请求、启动后台线程、获取request,response对象等功能,下面是一个进行异步处理的Servlet类:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

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

public class AsyncServlet extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {

    response.setContentType("text/html;charset=GBK");

    PrintWriter out = response.getWriter();

    out.println("进入Servlet的时间:" new Date() + ".<br/>");

    out.flush();

    AsyncContext acontext = request.startAsync();

    acontext.setTimeout(20*1000);

    acontext.start(new Executor(acontext));

    out.println("结束Servlet的时间:" new Date() + ".<br/>");

    out.flush();

  }

}

 

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

public class Executor implements Runnable {

  private AsyncContext context;

  public Executor(AsyncContext context) {this.context = context;}

  public void run(){

    try {

      Thread.sleep(5000);

      ServletRequest request = context.getRequest();

      List<String> books = new ArrayList<String>();

      books.add("book1"); books.add("book2"); books.add("book3");

      request.setAttribute("books", books);

      context.dispatch("/async.jsp");

    } catch (Exception e) {

      e.printStachTrace();

    }

  }

}

    在此Executor中,让线程睡眠5秒来模拟调用的耗时的业务方法,最后调用AsyncContext的dispatch方法把请求转发到指定的JSP页面。被异步请求的JSP页面需要指定session="false",表明该页面不会重新创建Session,下面是async.jsp的内容:

?


1

2

3

4

5

6

7

8

9

10

11

<%@ page contentType="text/html;chaset=GBK" language="java" session="fasle" %>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<ul>

  <c:forEach items="${books}" var="book" >

    <li>${book}</li>

  </c:forEach>

</ul>

<%

  out.println("业务调用结束的时间:" + new Date());

  request.getAsyncContext().complete();//完成异步调用

%>

    上面的页面只是一个JSP页面,只是使用了JSTL标签库来迭代输出books集合,因此需要将JSTL的两个Jar包复制到项目的lib目录中。

对于希望启用异步调用的Servlet而言,开发者必须显示指定开启异步调用,为Servlet开启异步调用有两种方式:1). 在@WebServlet中指定asyncSupported=true  2). 在web.xml的<servlet>元素中增加<async-supported>子元素,以下是一个配置片段:

?


1

2

3

4

5

6

7

8

9

<servlet>

  <servlet-name>async</servlet-name>

  <servlet-class>com.abc.AsyncServlet</servlet-class>

  <async-supported>true</async-supported>

</servlet>

<servlet-mapping>

  <servlet-name>async</servlet-name>

  <url-pattern>/async</url-pattern>

</servlet-mapping>

    对于支持异步调用的Servlet来说,当Servlet以异步方式启用新线程后,该Servlet的执行不会被阻塞,该Servlet将可以向客户端浏览器生成相应——当新线程执行完成后,新线程生成的相应将再次被送往客户端浏览器。

    当Servlet启用异步调用的线程之后,该线程的执行过程对开发者是透明的。但在有些情况下,开发者需要了解该异步线程的执行细节,并针对特定的执行结果进行针对性处理,这可以借助于Servlet3.0提供的异步监听器来实现。异步监听器需要实现AsyncListener接口,该接口中定义了如下方法:

  • onStartAsync(AsyncEvent event):当异步调用开始时触发该方法
  • onComplete(AsyncEvent event):当异步调用结束时触发该方法
  • onError(AsyncEvent event):当异步调用出错时触发该方法
  • onTimeout(AsyncEvent event):当异步调用超时时触发该方法

    下面是一个简单的监听器类:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

public class MyAsyncListener implements AsyncListener {

  public void onComplete(AsyncEvent event) {

    System.out.println("异步调用完成:" new Date());

  }

  public void onError(AsyncEvent event) {

    System.out.println("异步调用出错:" new Date());

  }

  public void onStartAsync(AsyncEvent event) {

    System.out.println("异步调用开始:" new Date());

  }

  public void onTimeout(AsyncEvent event) {

    System.out.println("异步调用超时:" new Date());

  }

}

提供了监听器之后,还需要通过AsynContext来注册此监听器,调用该对象的addListener()方法即可完成监听器的注册:

?


1

2

AsyncContext acontext = request.startAsync();

acontext.addListener(new MyAsyncListener());

时间: 2025-01-07 16:24:53

Servlet3.0提供的异步处理的相关文章

Sun向JCP提交Servlet3.0规范—JSR315

js|servlet|规范 Sun 已经向JCP(Java Community Process)提交了Servlet3.0规范--JSR 315(Java Specification Request).其高级目标包括可插拔web框架.EoD(ease of development--易于开发)特征.支持异步和Comet.安全.与其他规范结合.以及其它各项改进.它准备包含在Java EE 6中,Java EE 6的最终版大约于2008第4季度发布.预计不出2007年7月2日就会出评论. 以下是这些

ASP.NET 2.0 中的异步页功能应用

asp.net|异步 下载本文源代码:WickedCode0510.exe ASP.NET 2.0 提供了大量新功能,其中包括声明性数据绑定和母版页,成员和角色管理服务等.但我认为最棒的功能是异步页,接下来让我告诉您其中的原因. 当 ASP.NET 接收针对页的请求时,它从线程池中提取一个线程并将请求分配给该线程.一个普通的(或同步的)页在该请求期间保留线程,从而防止该线程用于处理其他请求.如果一个同步请求成为 I/O 绑定(例如,如果它调用一个远程 Web 服务或查询一个远程数据库,并等待调用

ASP.NET 2.0中的异步页功能应用

ASP.NET 2.0 提供了大量新功能,其中包括声明性数据绑定和母版页,成员 和角色管理服务等.但我认为最棒的功能是异步页,接下来让我告诉您其中的原 因. 当 ASP.NET 接收针对页的请求时,它从线程池中提取一个线程并将请求分配 给该线程.一个普通的(或同步的)页在该请求期间保留线程,从而防止该线程 用于处理其他请求.如果一个同步请求成为 I/O 绑定(例如,如果它调用一个 远程 Web 服务或查询一个远程数据库,并等待调用返回),那么分配给该请求 的线程在调用返回之前处于挂起状态.这影响

ASP.NET 2.0 中的异步页[来自MSDN]

ASP.NET 2.0 提供了大量新功能,其中包括声明性数据绑定和母版页,成员和角色管理服务等.但我认为最棒的功能是异步页,接下来让我告诉您其中的原因. 当 ASP.NET 接收针对页的请求时,它从线程池中提取一个线程并将请求分配给该线程.一个普通的(或同步的)页在该请求期间保留线程,从而防止该线程用于处理其他请求.如果一个同步请求成为 I/O 绑定(例如,如果它调用一个远程 Web 服务或查询一个远程数据库,并等待调用返回),那么分配给该请求的线程在调用返回之前处于挂起状态.这影响了可伸缩性,

Servlet3.0中Servlet的使用

1.注解配置        在以往我们的Servlet都需要在web.xml文件中进行配置(Servlet3.0同样支持),但是在Servlet3.0中引入了注解,我们只需要在对应的Servlet类上使用@WebServlet注解进行标记,我们的应用启动之后就可以访问到该Servlet.对于一个@WebServlet而言,有一个属性是必须要的,那就是它的访问路径.@WebServlet中有两个属性可以用来表示Servlet的访问路径,分别是value和urlPatterns.value和urlP

体验ASP.NET 2.0 中的异步页功能

asp.net|异步 (一).简单介绍实现原理 下图左为未使用异步页功能执行过程(Asp.net 1.0通常情况), 下图右为使用了异步页执行过程(Asp.net 2.0新增特性). (Asp.net 1.0一般处理过程) (使用Asp.net 2.0新增特性异步页功能处理过程) 从左图中看出,在一个页面整个请求的过程中, 一个线程始终为同一个页面的请求服务. 而从右图可以看出,在一个页面请求的过程中, 可以由不同的线程为本页面请求服务. 显然,采用图中方式在客户端请求数量多时,网站整体效率较高

未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序解决办法

  错误信息:未在本地计算机上注册"microsoft.ACE.oledb.12.0"提供程序. 解决办法: 去http://download.microsoft.com/download/7/0/3/703ffbcb-dc0c-4e19-b0da-1463960fdcdb/AccessDatabaseEngine.exe下载.然后安装就行了. 本错误是由于你使用了ACCESS2007版本建立的数据库,但服务器中没有相配合使用的程序,所以出错. 未在本地计算机上注册"micr

使用.netFx4.0提供的方法解决32位程序访问64位系统的64位注册表

原文:使用.netFx4.0提供的方法解决32位程序访问64位系统的64位注册表   我们知道目标平台是32位的程序运行在64位的系统上,去访问部分注册表的时候系统自动重定向到win32node节点对应的项去了.但是做过安装程序开发人员可能遇到过"需要去掉重定向"的问题,即直接访问64位程序的注册表. 网上有很多winAPI的方法,关闭注册表的重定向稍微复杂.(关闭文件系统的重定向稍微简单些,搬过来就可以用:关闭注册表的重定向我现在没看懂.) 我这里提供的方法不需要关闭重定向,也不需要

求大神帮助解决:未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序

问题描述 有关调用实时(JIT)调试而不是此对话框的详细信息,请参见此消息的结尾.**************异常文本**************System.InvalidOperationException:未在本地计算机上注册"Microsoft.Jet.OLEDB.4.0"提供程序.在System.Data.OleDb.OleDbServicesWrapper.GetDataSource(OleDbConnectionStringconstr,DataSourceWrapper