Servlets java.lang.IllegalStateException:调用[asyncDispatch()]对于异步状态为[COMPLETING]的请求无效
我有以下异步Servlet、相应的侦听器和异步处理器类 AsyncProcessor.java:Servlets java.lang.IllegalStateException:调用[asyncDispatch()]对于异步状态为[COMPLETING]的请求无效,servlets,tomcat7,java-ee-6,servlet-3.0,asynchronous,Servlets,Tomcat7,Java Ee 6,Servlet 3.0,Asynchronous,我有以下异步Servlet、相应的侦听器和异步处理器类 AsyncProcessor.java: public class AsyncProcessor implements Runnable { private AsyncContext asyncContext; public AsyncProcessor(AsyncContext asyncContext, String view) { this.asyncContext = asyncContext;
public class AsyncProcessor implements Runnable {
private AsyncContext asyncContext;
public AsyncProcessor(AsyncContext asyncContext, String view) {
this.asyncContext = asyncContext;
this.asyncContext.getRequest().setAttribute("dispatch", view);
}
public void run() {
try {
Thread.sleep(10*1000);
asyncContext.complete();
} catch(Exception e) {
}
}
}
MyServlet13.java:
@WebServlet(name="myServlet13", urlPatterns="/servlet13", asyncSupported=true)
public class MyServlet13 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
AsyncContext asyncContext = request.startAsync();
System.out.println("Before starting Async processing");
asyncContext.addListener(new MyAsyncListener());
Executor executor = (Executor)getServletContext().getAttribute("executor");
asyncContext.start(new AsyncProcessor(asyncContext, "/jsp13.jsp"));
System.out.println("After starting Async processing");
}
}
MyAsyncListener.java:
public class MyAsyncListener implements AsyncListener {
public void onStartAsync(AsyncEvent asyncEvent) throws IOException {
System.out.println("This is from onStartAsync");
}
public void onComplete(AsyncEvent asyncEvent) throws IOException {
System.out.println("This is from onComplete, before dispatch");
AsyncContext asyncContext = asyncEvent.getAsyncContext();
asyncContext.dispatch("/jsp13.jsp");
asyncContext.getResponse().getWriter().println("Async tasks completed...<br>");
System.out.println("This is from onComplete, after dispatch");
}
public void onTimeout(AsyncEvent asyncEvent) throws IOException {
System.out.println("This is from onTimeout");
}
public void onError(AsyncEvent asyncEvent) throws IOException {
System.out.println("This is from onError");
}
}
公共类MyAsyncListener实现AsyncListener{
公共void onStartAsync(AsyncEvent AsyncEvent)引发IOException{
System.out.println(“这是来自onStartAsync”);
}
public void onComplete(AsyncEvent AsyncEvent)引发IOException{
System.out.println(“这是从onComplete发送的,在发送之前”);
AsyncContext=asyncEvent.getAsyncContext();
asyncContext.dispatch(“/jsp13.jsp”);
asyncContext.getResponse().getWriter().println(“异步任务已完成…
”;
System.out.println(“这是从onComplete发送的,发送后”);
}
public void onTimeout(AsyncEvent AsyncEvent)引发IOException{
System.out.println(“这是来自onTimeout”);
}
public void onError(AsyncEvent AsyncEvent)引发IOException{
System.out.println(“这是来自onError”);
}
}
当我尝试用/servlet13 url模式调用MyServlet13
时,我得到以下异常
java.lang.IllegalStateException:调用[asyncDispatch()]对于异步状态为[COMPLETING]的请求无效
不确定这个代码有什么问题
根据servlet3.0规范,我们可以将AsyncListener添加到获得的AsyncContext
它将能够听到各种事件。在我的例子中,应该监听onComplete()
,并将请求发送到jsp13.jsp
视图(我的web应用程序上下文中确实有jsp13.jsp
)
我使用的是最新版本的tomcat 7.0.x和servlet 3.0规范,这是行不通的。您已完成请求,无法再次发送。complete()结束您的周期,响应已经发送。有趣的是,有时我会看到上面的错误,有时会看到一个空白页
FYI,调用AsyncListener的onComplete(),我可以在服务器控制台上看到“这是从onComplete发送的,发送后”