有时,来自 HttpServletRequest
的方法 req.startAsync()
会抛出 IllegalStateException
(响应已经关闭) .
如何检查请求状态以避免 IllegalStateException
?
req.isAsyncSupported()
总是返回true .
相关代码:
final HttpSession httpSession = req.getSession(false);
if (httpSession == null) {
resp.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
return;
}
final AsyncContext asynContext = req.startAsync(); //exception here`
例外:
12:28:12,735 ERROR [org.apache.catalina.core.ContainerBase . [jboss.web] . [default-host] . [/ esus] . [LongPollServlet]](http- / 0.0.0.0:8080-2 )JBWEB000236:servlet LongPollServlet的Servlet.service()抛出异常:java.lang.IllegalStateException:JBWEB000049:响应已经在org.apache.catalina.connector.Request.startAsync(Request.java:3180)已关闭[jbossweb-7.2 org.apache.catalina.connector.Request.startAsync(Request.java:3170)中的.0.Final-redhat-1.jar:7.2.0.Final-redhat-1] [jbossweb-7.2.0.Final-redhat -1.jar:7.2.0.Final-redhat-1]在org.apache.catalina.connector.RequestFacade.startAsync(RequestFacade.java:925)[jbossweb-7.2.0.Final-redhat-1.jar:7.2 com.performer.framework.server.LongPollServlet.continueDoPost(LongPollServlet.java:75)[st10.framework.webserver.jar:] com.performer.framework.server.LongPollServlet.doPost上的.0.Final-redhat-1] (LongPollServlet.java:62)[st10.framework.webserver.jar:]在javax.servlet.http.HttpServlet.service(HttpServlet.java:754)[jboss-servl et-api_3.0_spec-1.0.2.Final-redhat-1.jar:1.0.2.Final-redhat-1],位于javax.servlet.http.HttpServlet.service(HttpServlet.java:847)[jboss-servlet- api_3.0_spec-1.0.2.Final-redhat-1.jar:1.0.2.Final-redhat-1]在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:295)[jbossweb-7.2 . 0.Final-redhat-1.jar:7.2.0.Final-redhat-1] org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)[jbossweb-7.2.0.Final-redhat- 1.jar:7.2.0.Final-redhat-1]在org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)[jbossweb-7.2.0.Final-redhat-1.jar:7.2 . 0.Final-redhat-1]在org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:149)[jbossweb-7.2.0.Final-redhat-1.jar:7.2.0.Final-redhat- 1] at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50)[jboss-as-jpa-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat- 8]在org.jboss.as.jpa.interceptor.WebNonTxEmCloserV alve.invoke(WebNonTxEmCloserValve.java:50)[jboss-as-jpa-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]在org.jboss.as.web.security . 在org.apache.catalina.core.StandardHostValve中的SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:169)[jboss-as-web-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8] . 在org.apache.catalina.valves.ErrorReportValve.invoke中调用(StandardHostValve.java:145)[jbossweb-7.2.0.Final-redhat-1.jar:7.2.0.Final-redhat-1](ErrorReportValve.java: 97)[jbossweb-7.2.0.Final-redhat-1.jar:7.2.0.Final-redhat-1] org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:102)[jbossweb-7.2 .0.Final-redhat-1.jar:7.2.0.Final-redhat-1]在org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:336)[jbossweb-7.2.0.Final-redhat -1.jar:7.2.0.Final-redhat-1]在org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)[jbossweb-7.2.0.Final-redhat-1.jar:7.2 .0.Final-redhat-1]在org.apache.coyote.http11.Http11Pro tocol $ Http11ConnectionHandler.process(Http11Protocol.java:653)[jbossweb-7.2.0.Final-redhat-1.jar:7.2.0.Final-redhat-1] atg.apache.tomcat.util.net.JIoEndpoint $ java.lang.Thread.run中的Worker.run(JIoEndpoint.java:915) [jbossweb-7.2.0.Final-redhat-1.jar:7.2.0.Final-redhat-1] [rt . jar :1.6.0_34]
2 回答
根据startAsync()的文件:
似乎Tomcat将
isAsyncSupported()
设置为true
.您可以将
HttpServletRequest
对象中的async属性设置为true
:要么
您还必须在servlet前面添加:
您想要检查响应,而不是请求状态,因为
startAsync()
在原始时无法调用回复已结束 .您应该能够从代码中看到关闭响应的位置(例如,如果它在某处调用
response.close();
) . 你应该在此之前调用startAsync()
,或者在调用之后设置一个标志并在调用startAsync()
之前检查它 .如果您根本没有处理响应,可以尝试测试
HttpServletResponse
以查看它是否已关闭,但没有明确的方法可以做到:有关
isClosed()
实现的讨论,请参见this answer . 没有简单或推荐的方法,但是如果你是绝望的,这可能有效(未经测试),但它会写入响应输出流,这很危险:或者,您可以依赖
response.isCommitted()
(see doc)作为提交的响应通常会被关闭,但这不是确定的 - 它可以被关闭但不会被提交 .