好吧,这是一种异常行为,是我们的用例所需要的。我们正在使用处理程序拦截器在“preHandle”方法中“增加活动请求计数”。在“afterCompletion”方法中,我们减少活动请求计数器。到目前为止,一切都很好。同步调用是直截了当的。但是在异步的情况下,有第二个请求(DispatcherType:ASYNC)用于减少计数器,而主请求(DispatcherType:REQUEST)用于增加计数器。我们检查调度程序类型以避免双重增量。到目前为止一切顺利。
如果某些有问题的客户端在触发请求后断开连接,则会出现问题。在这种情况下,当主请求进入服务器但在异步线程启动之前客户端断开自身(如关闭浏览器)。在这种情况下,第二个请求(DispatcherType:ASYNC)根本没有被创建。这种情况使计数器增加(由主请求)。 对于我们的用例,我们必须减少计数器,无论它是否为请求增加。 在这里期待您的帮助/建议。提前致谢。
其他细节: Spring Boot 应用 Spring framework: 4.3.4.RELEASE Tomcat : 7 Using RestController Handler Interceptor: AsyncHandlerInterceptor 在异步模式下我们使用 ResponseBodyEmitter 向客户端发送数据
登录服务器:
Exception in thread "pool-87-thread-1" java.lang.IllegalStateException: The request associated with the **AsyncContext has already completed processing**.
at org.apache.catalina.core.AsyncContextImpl.check(AsyncContextImpl.java:497)
at org.apache.catalina.core.AsyncContextImpl.getRequest(AsyncContextImpl.java:209)
at org.apache.catalina.core.AsyncContextImpl.dispatch(AsyncContextImpl.java:198)
at org.apache.catalina.core.AsyncContextImpl.dispatch(AsyncContextImpl.java:170)
at org.apache.catalina.core.AsyncContextImpl.dispatch(AsyncContextImpl.java:164)
at org.springframework.web.context.request.async.StandardServletAsyncWebRequest.dispatch(StandardServletAsyncWebRequest.java:123)
at org.springframework.web.context.request.async.WebAsyncManager.setConcurrentResultAndDispatch(WebAsyncManager.java:353)
at org.springframework.web.context.request.async.WebAsyncManager.access$200(WebAsyncManager.java:58)
at org.springframework.web.context.request.async.WebAsyncManager$7.handleResult(WebAsyncManager.java:416)
at org.springframework.web.context.request.async.DeferredResult.setResultInternal(DeferredResult.java:199)
at org.springframework.web.context.request.async.DeferredResult.setErrorResult(DeferredResult.java:214)
at org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitterReturnValueHandler$HttpMessageConvertingHandler.completeWithError(ResponseBodyEmitterReturnValueHandler.java:219)
at org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter.completeWithError(ResponseBodyEmitter.java:204)
at org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter.sendInternal(ResponseBodyEmitter.java:169)
at org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter.send(ResponseBodyEmitter.java:159)
at net.atpco.pipeline.common.post.KryoResponseEmitterPostBox.send(KryoResponseEmitterPostBox.java:48)
at net.atpco.pipeline.common.post.KryoResponseEmitterPostBox.lambda$0(KryoResponseEmitterPostBox.java:37)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
更新: 在进一步的研究中,我在 spring 文档中发现了这一点......“请注意,当异步请求超时或因网络错误而完成时,HandlerInterceptor 实现可能需要工作。对于这种情况,Servlet 容器不会调度,因此 postHandle “ _ _ 这个 deferredResultInterceptor 似乎解决了这个问题。