Servlet-异步执行AsyncContext
2015年9月18日
启用异步:@WebServlet(value="/b.do",asyncSupported=true)
设置响应内容类型:response.setContentType("text/html;charset=GBK");
注意:如果不设置响应内容类型,将无法启用异步。
开启新线程:使用AsyncContext开启新的线程实例。
AsyncContext ctx=request.startAsync();
ctx.setTimeout(30*1000);
ctx.start(new Task(ctx));
设置异步上下文:AsyncContext实例:
public Task(AsyncContext ctx) {
super();
this.ctx = ctx;
}
private AsyncContext ctx=null;
处理请求:处理完成后可以转发(dispatch)或结束(complete)。
ServletRequest req=ctx.getRequest();
req.setAttribute("async", "This is anasync msg:"+new Date());
ctx.dispatch("/a.jsp");
//AsynServlet.java
package lee;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
importjavax.servlet.AsyncContext;
importjavax.servlet.ServletException;
importjavax.servlet.annotation.WebServlet;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class AsynServlet
*/
@WebServlet(value="/b.do",asyncSupported=true)
public class AsynServletextends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public AsynServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @seeHttpServlet#service(HttpServletRequest request, HttpServletResponse response)
*/
protected void service(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("text/html;charset=GBK");
PrintWriter out=response.getWriter();
out.println("Start="+newDate()+"</br>");
out.flush();
AsyncContextctx=request.startAsync();
ctx.setTimeout(30*1000);
ctx.start(newTask(ctx));
out.println("Main Return="+newDate()+"</br>");
out.flush();
}
}
//工作线程:Task.java
package lee;
import java.util.Date;
importjavax.servlet.AsyncContext;
importjavax.servlet.ServletRequest;
public class Task implementsRunnable {
public Task(AsyncContext ctx) {
super();
this.ctx= ctx;
}
private AsyncContext ctx=null;
@Override
public void run() {
// TODO Auto-generated method stub
try {
System.out.println("start task."+new Date());
Thread.sleep(5000);
ServletRequestreq=ctx.getRequest();
req.setAttribute("async","This is an async msg:"+new Date());
ctx.dispatch("/a.jsp");
System.out.println("finish task."+newDate());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//a.jsp
<%@ pagelanguage="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"session="false"%>
<!DOCTYPE html PUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<metahttp-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Insert titlehere</title>
</head>
<body>
this is a.jsp
<%="aync return="+new java.util.Date() %>
<%=request.getAttribute("async")%>
</body>
</html>
异步监听对象:AsyncListener对象。包括开始、结束、出错、超时的监听。
注意:onStartAsync()不会被调用。因为是startAsync()之后才添加的监听对象。
添加异步监听对象:addListener()。
ctx.addListener(newAL1());
参考:
http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/plain/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncContextListenersTest.java
https://java.net/projects/servlet-spec/lists/users/archive/2013-12/message/1
//AsynServlet.java
package lee;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
importjavax.servlet.AsyncContext;
importjavax.servlet.ServletException;
importjavax.servlet.annotation.WebServlet;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class AsynServlet
*/
@WebServlet(value="/b.do",asyncSupported=true)
public class AsynServletextends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public AsynServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#service(HttpServletRequestrequest, HttpServletResponse response)
*/
protected void service(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("text/html;charset=GBK");
PrintWriter out=response.getWriter();
out.println("Start="+newDate()+"</br>");
out.flush();
request.setAttribute("org.apache.catalina.ASYNC_SUPPORTED",true);
AsyncContext ctx=request.startAsync();
ctx.addListener(newAL1());
ctx.setTimeout(30*1000);
ctx.start(new Task(ctx));
out.println("Main Return="+newDate()+"</br>");
out.flush();
}
}
//AL1.java
package lee;
import java.io.IOException;
import java.util.Date;
importjavax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
public class AL1 implementsAsyncListener {
@Override
publicvoid onComplete(AsyncEvent arg0) throws IOException {
// TODO Auto-generated method stub
System.out.println("Listener=onComplete."+newDate());
}
@Override
publicvoid onError(AsyncEvent arg0) throws IOException {
// TODO Auto-generated method stub
System.out.println("Listener=onError."+newDate());
}
@Override
publicvoid onStartAsync(AsyncEvent arg0) throws IOException {
// TODO Auto-generated method stub
System.out.println("Listener=onStartAsync."+newDate());
}
@Override
publicvoid onTimeout(AsyncEvent arg0) throws IOException {
// TODO Auto-generated method stub
System.out.println("Listener=OnTimeout."+newDate());
}
}
//工作线程:Task.java
package lee;
import java.util.Date;
importjavax.servlet.AsyncContext;
importjavax.servlet.ServletRequest;
public class Task implementsRunnable {
public Task(AsyncContext ctx) {
super();
this.ctx = ctx;
}
private AsyncContext ctx=null;
@Override
public void run() {
// TODO Auto-generated method stub
try {
System.out.println("start task."+newDate());
Thread.sleep(5000);
ServletRequest req=ctx.getRequest();
req.setAttribute("async", "This is anasync msg:"+new Date());
ctx.dispatch("/a.jsp");
System.out.println("finish task."+newDate());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//a.jsp
<%@ pagelanguage="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"session="false"%>
<!DOCTYPE html PUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<metahttp-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Insert titlehere</title>
</head>
<body>
this is a.jsp
<%="aync return="+new java.util.Date() %>
<%=request.getAttribute("async") %>
</body>
</html>
//结果输出