从HttpServletRequest获取AsyncContext

3
我正在使用Spring的OncePerRequestFilter,覆盖shouldNotFilterAsyncDispatch方法并返回false。这样它就可以处理异步请求。在过滤器中,我尝试执行以下操作:
if (isAsyncDispatch(request)) {
    request.getAsyncContext().addListener(new AsyncListener() {
        @Override
        public void onComplete(AsyncEvent event) throws IOException {
            System.out.println("onComplete");
        }

        @Override
        public void onTimeout(AsyncEvent event) throws IOException {

        }

        @Override
        public void onError(AsyncEvent event) throws IOException {
            System.out.println("onError");
        }

        @Override
        public void onStartAsync(AsyncEvent event) throws IOException {

        }
    });
}

所以isAsyncDispatch返回了预期的true。但是当我尝试使用getAsyncContext时,会出现以下异常:

IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)

实际上,request.isAsyncStarted()返回false,但是request.isAsyncSupported()为true,并且request.getDispatcherType()ASYNC

我不明白:它是异步的还是不是?也许我在错误地使用API?如何添加AsyncListener?也许是因为我正在使用Tomcat?

提前感谢!


1
据我所知,请求在DispatcherServlet的某个地方开始异步处理。更准确地说,在处理返回某种异步结果的实际请求映射方法时。因此,如果这段代码在预请求端的过滤器中,那么startAsync()方法还没有被调用。 - Adam Hošek
1个回答

1
当我过去做过这件事时,我们所做的是:

if (request.isAsyncSupported()) {
      AsyncContext asyncContext = request.startAsync();
      // Do whatever with context
}

getAsyncContext() 的 javadoc(在 ServletRequest 中)指出:

如果该请求没有进入异步模式,即未调用 startAsync() 或 startAsync(ServletRequest,ServletResponse),则会抛出 IllegalStateException 异常。


谢谢,现在我能够添加监听器了。 但这会启动异步操作,不是吗? 我在Spring控制器中的操作结果是“Future”。 所以我认为它已经是异步的了。 它还会为其他请求启动异步处理,但我只需要对异步控制器方法使用它。 - Dmitry Senkovich

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接