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>
在jsp界面使用jstl表达式的时候需要使用jstl两个jar包,jstl.jar及standard.jar