今天发现tomcat7发布bate版了,对Servlet3的支持令值得期待,尤其是异步这个特性,
之前bate版都没有,只有拉它主干自己编译tomcat跑的。赶紧来尝试下吧~
在我们项目中,应用异步最典型场景就是订购后等待开通这个等待过程了,
在之前Servlet版本,一个请求必须要完全处理完后才能返回,这样等待开通后跳转到产品
就必须要去轮询有没有权限了,如果可以异步,那一个请求就能搞定。
模拟如下
首先要把tomcat7中的servlet-api.jar 和tomcat-api.jar 加到eclipse引用中,这样可以开发而打包的时候不会包含这两个jar,直接在tomcat7上跑
@WebServlet(name="Servlet3", urlPatterns={"/demo", "/servlet"},asyncSupported=true)//此为Servlet3新增的注解支持,asyncSupported=true表示支持异步
//也可在web.xml中添加<async-supported>true</async-supported>
public class Servlet3 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.println("下订单开始: " + new Date() + "<br/>");
out.flush();
AsyncContext ctx = req.startAsync();
//异步去执行开通订单
new Thread(new CheckOrder(ctx)).start();
out.println("订购成功: " + new Date()+ "<br/>");
out.flush();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
public class CheckOrder implements Runnable{
private AsyncContext ctx = null;
public CheckOrder(AsyncContext ctx) {
this.ctx = ctx;
}
public void run() {
try {
//模拟开通等待
Thread.sleep(3000);
PrintWriter out = ctx.getResponse().getWriter();
out.println("已经有权限了,let's go! : " + new Date() );
out.flush();
ctx.complete();
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果
下订单开始: Thu Jul 08 15:49:30 CST 2010
订购成功: Thu Jul 08 15:49:30 CST 2010
订购成功: Thu Jul 08 15:49:30 CST 2010
没有等待那个模拟开通就直接返回了,过了三秒在打印出
已经有权限了,let's go! : Thu Jul 08 15:49:33 CST 2010
这样好处是一个请求就能解决原来多次请求,减少了请求数,但也可以看到,在打印出前面的结果后,这个请求连接一直
保持的,这就考验了服务器了,因为个人感觉适合于立刻返回处理结果,但后续异步操作也能快速返回的情景,如果说异步操
作的时间很长就不适合了,还是原来那种再发起请求的好。
大家讨论拍砖,Servlet3其他新特性,还是值得研究。