Servlets 异步Servlet-首选实现
最近,在我研究Servlets 异步Servlet-首选实现,servlets,asynchronous,java-ee-6,servlet-3.0,java-ee-7,Servlets,Asynchronous,Java Ee 6,Servlet 3.0,Java Ee 7,最近,在我研究servlet中的异步处理时,我至少遇到了三种实现方法 有些功能使用这种方法 问题是: 哪一个是最好的 也许这些方法中有一些是不推荐的 也许还有一种方法比下面提到的更好 找到的方法: 使用AsyncContext.start(Runnable) 这种方法非常简单和直接。但许多服务器在为HTTP请求创建的线程池中执行这样的作业 (更多信息请参见此处) 使用Servlet上下文初始化期间创建的自定义线程池 (此处示例:)。 但我可以在Servlet容器中创建自己的线程吗?在EJB(在
servlet
中的异步处理时,我至少遇到了三种实现方法
有些功能使用这种方法
问题是:
AsyncContext.start(Runnable)
这种方法非常简单和直接。但许多服务器在为HTTP
请求创建的线程池中执行这样的作业
(更多信息请参见此处)
EJB
(在JavaEE7
之前)中不建议(甚至禁止)使用它。
我可以使用JavaSE
执行器还是应该使用JavaEE7
中的ManagedExecutors
(假设我使用JavaEE7
)
EJB
和@asynchronous
注释
(此处示例:)。
但在这里,我无法控制执行任务的线程(即应该创建多少线程等)
我很高兴听到您对这个问题的看法,以及您使用
AsyncContext
的经验,所有线程都将具有相同的性能,在后端,所有线程都将请求处理线程替换为另一个线程,以便可以处理更多的请求
下面是一个简单的实现:
@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");
}
}
@WebServlet(urlPatterns=“/AsyncLongRunningServlet”,asyncSupported=true)
公共类AsyncLongRunningServlet扩展了HttpServlet{
私有静态最终长serialVersionUID=1L;
受保护的无效数据集(HttpServletRequest请求,
HttpServletResponse响应)引发ServletException,IOException{
System.out.println(“请求处理线程”+线程.currentThread().getName());
setAttribute(“org.apache.catalina.ASYNC_-SUPPORTED”,true);
response.setContentType(“text/html”);
PrintWriter PrintWriter=response.getWriter();
printWriter.println(“异步servlet”);
printWriter.println(“请求处理线程”+线程.currentThread().getName());
printWriter.println(“
”);
printWriter.println(“”);
printWriter.println(“
”);
AsyncContext asyncCtx=request.startAsync();
addListener(新的AppAsyncListener());
asyncCtx.setTimeout(12000);
//释放请求处理线程
asyncCtx.start(()->{
printWriter.println(“
”);
printWriter.println(“异步线程名称”+线程.currentThread().getName());
printWriter.println(“
”);
int i=0;
而