⑩异步处理
前言
系列出品:http://www.cnblogs.com/Alandre/category/552859.html
Servlet3.0提供异步处理
在以前的Servlet规范化,如果Servlet作为控制器调用了一个耗时的业务方法,那么必须等到业务方法完全返回之后才能生成响应,这将使用Servlet对业务方法的调用变成一种阻塞式的调用,因此效率比较低。
Servlet3.0规范引入了异步处理来解决这个问题,异步处理允许Servlet重新发起一条新线程去调用 耗时业务方法,这样就可以避免等待。
Servlet3.0的异步处理是通过AsyncContext类来处理的,Servlet可通过ServletRequest的如下两个方法开启异步调用,创建AsyncContext对象:
AsyncContext startAsync()
AsyncContext startAsync(ServletRequest,ServletResponse)
异步处理类AsyncServlet.java
package aniyo.servlet.async; import java.io.IOException; import java.io.PrintWriter; import java.util.Date; import javax.servlet.AsyncContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet 3.0提供的异步处理 * 异步操作通过AsyncContext类来处理,通过startAsync()方法来开启异步调用 * @author aniyo * blog:http://aniyo.iteye.com * */ @WebServlet(name="asyncServle",urlPatterns="/asyncServlet",asyncSupported=true) public class AsyncServlet extends HttpServlet { /* (non-Javadoc) * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=GBK"); PrintWriter out = response.getWriter(); out.println("<title>异步调用示例</title>"); out.println("进入Servlet的时间:"+new Date()+".<br/>"); out.flush(); //创建AsyncContext,开始异步调用 AsyncContext actx = request.startAsync(); //设置异步调用的超时时长 actx.setTimeout(30*1000); //启动异步调用的线程 actx.start(new Executor(actx)); out.println("结束Servlet的时间:"+new Date()+".<br/>"); out.flush(); } }
线程类Executor.java
package aniyo.servlet.async; import java.util.ArrayList; import java.util.List; import javax.servlet.AsyncContext; import javax.servlet.ServletRequest; public class Executor implements Runnable{ private AsyncContext actx = null; public Executor(AsyncContext actx) { this.actx = actx; } /* (non-Javadoc) * @see java.lang.Runnable#run() */ @Override public void run() { //等待5秒 try { Thread.sleep(5*1000); ServletRequest request = actx.getRequest(); List<String> books = new ArrayList<String>(); books.add("java"); books.add("oracle"); books.add("j2ee"); request.setAttribute("books", books); actx.dispatch("/async.jsp"); } catch (InterruptedException e) { e.printStackTrace(); } } }
async.jsp
<%@page import="java.util.Date"%> <%@ 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" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <ul> <c:forEach items="${books}" var="book"> <li> ${book } </li> </c:forEach> </ul> <%out.println("业务调用结束的时间:"+ new Date()); //完成异步调用 //request.getAsyncContext().complete(); %> </body> </html>