博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Servlet3.0 异步处理机制
阅读量:6279 次
发布时间:2019-06-22

本文共 2113 字,大约阅读时间需要 7 分钟。

hot3.png

在早前版本的Servlet规范中,如果Servlet作为控制器调用了一个较耗时的业务方法,那么Servlet必须等到业务方法完全返回之后才生成响应,这使得Servlet对业务方法的调用变成一种阻塞式的调用,从而导致运行效率降低。

Servlet3.0规范引入了异步处理来解决这个问题,异步处理允许Servlet重新发起一条新线程去调用较耗时的业务方法,这样就可避免等待。该异步机制是通过AsyncContext类来处理的,Servlet可通过ServletRequest的如下两个方法开启异步调用、创建AsyncContext对象:

1、AsyncContext startAsync()

   2、AsyncContext startAsync(ServletRequest,ServletResponse)

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

Code demo:

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

public class AsyncServlet extends HttpServlet

{

   @Override

   public void doGet(HttpServletRequest request,HttpServletResponse response)throws IOException,ServletException{

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

   PrinterWriter out = response.getWriter();

   out.println("<title>异步</tilte>");

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

   out.flush();

  // 创建AsyncContext,开始异步调用

  AsyncContext actx = request.startAsync();

  // 设置异步调用的超时时长

  actx.setTimeout(30*1000);

  // 启动异步调用的线程

  actx.start(new Executor(actx));

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

  out.flush();

   }

}

 

Excutor.java:

public class Executor implements Runnable

{

   pirvate AyncContext actx = null;

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

 public void run()

{

   try{

      // 等待10秒,模拟业务方法的执行

    Thread.sleep(10 * 1000);

    ServletRequest request = actx.getRequest();

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

    books.add("Thinking in  java");

   books.add("Effective java");

   books.add("Core Java");

request.setAttribute("books",books);

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

     }catch(Exception e){   e.printStackTrace();    }

    }

}

该线程执行体内让线程暂停10秒钟来模拟调用耗时的业务方法,最后调用 AsyncContext的dispatch方法把请求dispatch到指定的JSP页面。

被 异步请求dispatch的目标页面需要指定session="false",表明该页面不会重新创建 session。

async.jsp:

<% page contentType="text/html;charset=GBK" language="java" session="false"%>

<% taglib prefix="c" uri="" %>

<ul>

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

      <li>${book}</li>

  </c:forEach>

</ul>

<%

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

  request.getAsyncContext().complete();

%>

转载于:https://my.oschina.net/u/938966/blog/118284

你可能感兴趣的文章
关于typedef的用法总结
查看>>
Apache用户认证、域名跳转、访问日志格式
查看>>
mwArray类说明
查看>>
CMD命令行:查看 Windows 操作系统的安装时间
查看>>
mysql explain
查看>>
golang交叉编译工具,gox使用入门
查看>>
Redis Master-Slave 读写分离测试
查看>>
git bash常用命令行以及初次接触yo以及bower
查看>>
修改MySQL默认空密码
查看>>
spring mvc访问静态文件(css/js/img)访问不到
查看>>
spring boot框架学习学前掌握之重要注解(1)-sprng的java配置方式
查看>>
plsql 书籍基础表结构
查看>>
nginx 第三方模块 modsecurity安装使用
查看>>
Kettle使用问题记录
查看>>
Android 透明(沉浸式)状态栏设计
查看>>
关于UIView的autoresizingMask属性
查看>>
sparkSQL UDF创建
查看>>
spring4中获取泛型的bean
查看>>
Ansible notes
查看>>
js实现二叉树
查看>>