注解实现SpringMVC异步处理中的问题

异常: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());
            }
        });

猜你喜欢

转载自blog.csdn.net/u014653854/article/details/80906794