Async Servlet - 首选实现

时间:2014-04-23 09:40:09

标签: servlets asynchronous java-ee-6 servlet-3.0 java-ee-7

最近,在我对Servlets中的异步处理的研究中,我遇到了至少三种实现方式 使用这种方法的一些功能。

问题是:

  1. 哪一个最好?
  2. 可能不建议使用其中一些方法吗?
  3. 也许还有另一种方法比下面提到的方法更好?
  4. 找到方法:

    1. 使用AsyncContext.start(Runnable)

      这种方法非常简单明了。但是许多服务器在为HTTP请求创建的线程池中执行这样的工作 (更多关于它http://www.nurkiewicz.com/2012/05/javaxservletservletrequeststartasync.html

    2. 使用在Servlet上下文初始化期间创建的自定义线程池

      (示例:http://www.journaldev.com/2008/async-servlet-feature-of-servlet-3)。 但我可以在Servlet容器中创建自己的线程吗? EJBJavaEE7之前)不推荐(甚至禁止)。 我可以使用JavaSE执行人员,还是应该使用ManagedExecutors中的JavaEE7(假设我使用JavaEE7)?

    3. 使用EJB@Asynchronious注释

      (例如:https://github.com/wildfly/quickstart/tree/master/servlet-async/src/main/java/org/jboss/as/quickstarts/servlet/async)。 但是在这里我无法控制执行我的任务的线程(即应该创建多少线程等)。

    4. 我很高兴听到您对此问题的看法以及您对AsyncContext的体验。

1 个答案:

答案 0 :(得分:2)

全部将具有相同的性能,在后端,所有线程都将请求处理线程替换为另一个线程,以便可以处理更多请求。

下面您将找到一个简单的实现:

@WebServlet(urlPatterns = "/AsyncLongRunningServlet", asyncSupported = true)
public class AsyncLongRunningServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
        System.out.println("Request Processing Thread "+Thread.currentThread().getName());

        request.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", true);
        response.setContentType("text/html");
        PrintWriter printWriter=response.getWriter();
        printWriter.println("<html><head><title>Asynchronous servlet</title></head><body>");
        printWriter.println("Request Processing Thread "+Thread.currentThread().getName());
        printWriter.println("<br>");
        printWriter.println("<progress id='progress' max='100')></progress>");
        printWriter.println("<br>");

        AsyncContext asyncCtx = request.startAsync();
        asyncCtx.addListener(new AppAsyncListener());
        asyncCtx.setTimeout(12000);
        //release of request processing thread
        asyncCtx.start(() ->{
            printWriter.println("<br>");
            printWriter.println("Async thread Name "+Thread.currentThread().getName());
            printWriter.println("<br>");

            int i=0;
            while(i<100)
            {
                printWriter.println("<script>document.getElementById('progress').value=\""+i+"\";</script>");
                printWriter.flush();
                try {
                    Thread.sleep(100);
                } catch (Exception e) {
                }
                i++;
            }
            printWriter.println("</body></html>");
            asyncCtx.complete();
        }

    );
        printWriter.println("<br>");
        printWriter.println("End of response");
    }

}



package com.journaldev.servlet.async;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebListener;

@WebListener
public class AppAsyncListener implements AsyncListener {

    @Override
    public void onComplete(AsyncEvent asyncEvent) throws IOException {
        System.out.println("AppAsyncListener onComplete");
        // we can do resource cleanup activity here
    }

    @Override
    public void onError(AsyncEvent asyncEvent) throws IOException {
        System.out.println("AppAsyncListener onError");
        //we can return error response to client
    }

    @Override
    public void onStartAsync(AsyncEvent asyncEvent) throws IOException {
        System.out.println("AppAsyncListener onStartAsync");
        //we can log the event here
    }

    @Override
    public void onTimeout(AsyncEvent asyncEvent) throws IOException {
        System.out.println("AppAsyncListener onTimeout");
        //we can send appropriate response to client
        ServletResponse response = asyncEvent.getAsyncContext().getResponse();
        PrintWriter out = response.getWriter();
        out.write("TimeOut Error in Processing");
    }

}