从 HttpServletRequest 获取 AsyncContext

Posted

技术标签:

【中文标题】从 HttpServletRequest 获取 AsyncContext【英文标题】:Get AsyncContext from HttpServletRequest 【发布时间】:2018-02-07 23:22:36 【问题描述】:

我正在使用 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?

提前谢谢你!

【问题讨论】:

AFAIK 请求在 DispatcherServlet 的某处开始异步。或者更准确地说,在处理返回一种异步结果的实际请求映射方法时。因此,如果此代码在预请求端的过滤器中,则尚未调用 startAsync() 方法。 【参考方案1】:

当我过去这样做时,我们已经这样做了:

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

getAsyncContext() 的 javadoc 声明:(在 ServletRequest 中)

IllegalStateException - 如果此请求尚未进入异步模式,即 startAsync() 和 startAsync(ServletRequest,ServletResponse) 均未调用

【讨论】:

谢谢,伙计,现在我可以给听众做广告了。但它会启动异步操作,不是吗?由于 Spring 控制器中的操作,我有 Future。所以我认为它已经是异步的。它也开始对其他请求进行异步处理,但我只需要异步控制器方法

以上是关于从 HttpServletRequest 获取 AsyncContext的主要内容,如果未能解决你的问题,请参考以下文章

如何从 HttpServletRequest 获取完整的 url? [复制]

从 HttpServletRequest 获取 AsyncContext

从 HttpServletRequest 获取 XML 并用于端点

无法从 HttpServletRequest 获取数据

如何从 HttpServletRequest 获取请求 url [重复]

如何从httpservletrequest requset获取requestid