Servlet3.0 異步處理機制

在早前版本的Servlet規範中,若是Servlet做爲控制器調用了一個較耗時的業務方法,那麼Servlet必須等到業務方法徹底返回以後才生成響應,這使得Servlet對業務方法的調用變成一種阻塞式的調用,從而致使運行效率下降。 html

Servlet3.0規範引入了異步處理來解決這個問題,異步處理容許Servlet從新發起一條新線程去調用較耗時的業務方法,這樣就可避免等待。該異步機制是經過AsyncContext類來處理的,Servlet可經過ServletRequest的以下兩個方法開啓異步調用、建立AsyncContext對象: java

一、AsyncContext startAsync() session

   二、AsyncContext startAsync(ServletRequest,ServletResponse) 異步

重複調用上面的方法將獲得同一個AyncContext對象,AyncContext對象表明異步處理的上下文,它提供了一些工具方法,能夠完成設置異步調用的超時時長,dispatch用於請求,啓動後臺線程、獲取request response對象等功能 jsp

Code demo: async

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

public class AsyncServlet extends HttpServlet 工具

{ this

   @Override url

   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();

%>

相關文章
相關標籤/搜索