Servlet3.0 异步处理机制

在早前版本的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="http://java.sun.com/jsp/jstl/core" %>

<ul>

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

      <li>${book}</li>

  </c:forEach>

</ul>

<%

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

  request.getAsyncContext().complete();

%>

你可能感兴趣的:(异步处理,servlet3.0)