学习Servlet中的异步处理 —— Servlet3.0中的Async支持
servlet的@WebServlet注解写法:
/**
* asyncSupported属性默认是false,如果需要开启支持异步处理功能,需要设置为true
*/
@WebServlet(name = "ServletAsyn", urlPatterns = "/ServletAsyn", asyncSupported = true)
AsynFilter的@WebServlet注解写法:
@WebFilter(filterName="AsynFilter",asyncSupported=true,value={"/ServletAsyn"},dispatcherTypes={DispatcherType.REQUEST,DispatcherType.ASYNC})
测试过程:
打开浏览器输入项目servlet地址:
http://localhost:8080/ServletAsynFilter/ServletAsyn
后台输出如图:
浏览器输出如图:
总结:
输入servlet请求地址,出发过滤器,过滤器方法开始执行,然后servlet的dopost方法开始执行,于是,创建了内部类的一个异步线程。在线程还没有完成的时候,servlet继续往下执行。最后,线程的任务完成返回浏览器页面。
下面是代码:
ServletAsyn.java
package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* autor:xanwidtf@foxmail.com
*/
/**
* Servlet implementation class ServletAsyn
*/
@WebServlet(name = "ServletAsyn", urlPatterns = "/ServletAsyn", asyncSupported = true)
public class ServletAsyn extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public ServletAsyn() {
super();
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//response.getWriter().append("Served at: ").append(request.getContextPath());
System.out.println("Servlet执行开始时间:"+new Date());
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
Date date = new Date(System.currentTimeMillis());
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
out.print("<h1>");
out.println("Servlet begin --" + sdf.format(date) + "<br>");// 响应输出到客户端
out.print("</h1>");
out.print("<hr>");
/*
* 体现异步思想,Servlet执行结束,而异步的线程仍然在继续跑
*/
AsyncContext context=request.startAsync();
new Thread(new Executor(context)).start(); //new Thread 传递AsyncContext对象 并且start
System.out.println("Servlet执行结束时间:"+new Date());
}
//内部类实现线程
public class Executor implements Runnable{
private AsyncContext context;
public Executor(AsyncContext context){
this.context=context;
}
@Override
public void run() {
//执行相关复杂业务
try {
Thread.sleep(1000*3);
context.getRequest();
context.getResponse();
ServletResponse response = context.getResponse();
PrintWriter out = response.getWriter();
Date date = new Date(System.currentTimeMillis());
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
out.print("<h1>");
out.println("Thread worker finished --"+ sdf.format(date));// 响应输出到客户端
out.print("</h1><hr>");
out.flush();
System.out.println("业务完成时间:"+new Date());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
Filter.java
package Filter;
import java.io.IOException;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
@WebFilter(filterName="AsynFilter",asyncSupported=true,value={"/ServletAsyn"},dispatcherTypes={DispatcherType.REQUEST,DispatcherType.ASYNC})
public class AsynFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
System.out.println("Start.....AsynFilter");
arg2.doFilter(arg0, arg1);
System.out.println("End....AsynFilter");
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}