异常:Exception in thread “http-apr-8080-exec-6” java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)
注解实现SpringMVC的异步处理,代码如下:
/**
* 注解实现SpringMVC的异步处理
*/
@WebServlet(urlPatterns = "/asynOrder", asyncSupported = true)
public class AsynServlet extends HttpServlet {
//支持异步处理asyncSupported = true
//重写doGet方法
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("主线程开始..... "+Thread.currentThread()+" start "+ System.currentTimeMillis());
AsyncContext startAsync = req.startAsync();
startAsync.start(new Runnable() {
@Override
public void run() {
System.out.println("子线程开始..... "+Thread.currentThread()+" start "+ System.currentTimeMillis());
try {
//业务处理逻辑;
} catch (Exception e) {
e.printStackTrace();
}
startAsync.complete();
AsyncContext asyncContext = req.getAsyncContext();
ServletResponse response = asyncContext.getResponse();
try {
response.getWriter().write("order success...");
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("子线程结束..... "+Thread.currentThread()+" end "+ System.currentTimeMillis());
}
});
System.out.println("主线程结束..... "+Thread.currentThread()+" end "+ System.currentTimeMillis());
//主线程的资源断开
}
}
运行结果的异常信息如下:
Exception in thread "http-apr-8080-exec-6" java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)
at org.apache.catalina.connector.Request.getAsyncContext(Request.java:1740)
at org.apache.catalina.connector.RequestFacade.getAsyncContext(RequestFacade.java:1047)
at com.enjoy.sevlet.OrderAsynServlet$1.run(AsynServlet.java:37)
at org.apache.catalina.core.AsyncContextImpl$RunnableWrapper.run(AsyncContextImpl.java:598)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
问题:AsyncContext.complete();方法的调用时机错误,应该在子线程完全处理完成业务逻辑的最后调用。调整代码之后,正常运行。
代码如下:
startAsync.start(new Runnable() {
@Override
public void run() {
System.out.println("子线程开始..... "+Thread.currentThread()+" start "+ System.currentTimeMillis());
try {
//业务处理;
} catch (Exception e) {
e.printStackTrace();
}
AsyncContext asyncContext = req.getAsyncContext();
ServletResponse response = asyncContext.getResponse();
try {
response.getWriter().write("order success...");
} catch (IOException e) {
e.printStackTrace();
}
startAsync.complete();
System.out.println("子线程结束..... "+Thread.currentThread()+" end "+ System.currentTimeMillis());
}
});