提问人:user1391606 提问时间:10/11/2015 最后编辑:user1391606 更新时间:2/18/2016 访问量:1461
将 tomcat 7.0.59 升级到 7.0.61:提交响应后无法创建会话
Upgrade tomcat 7.0.59 to 7.0.61 : Cannot create a session after the response has been committed
问:
我们正在从 Tomcat 7.0.59 升级到 7.0.61 并收到以下错误。
仅当通过 Apache 代理(无 SSL)传递时,才会发生此错误。
当从浏览器(没有 Apache 代理)调用 Tomcat 上下文时,它可以正常工作。
有没有人遇到过相同/类似的问题?
我们确实查看了更新日志(https://tomcat.apache.org/tomcat-7.0-doc/changelog.html),但我们在 Tomcat 7.0.61 中找不到任何解释此行为的更改
SEVERE: Servlet.service() for servlet [CaptchaServlet] in context with path [/cw] threw exception
java.lang.IllegalStateException: Cannot create a session after the response has been committed
at org.apache.catalina.connector.Request.doGetSession(Request.java:3008)
at org.apache.catalina.connector.Request.getSession(Request.java:2384)
at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:897)
at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:909)
at be.servlet.CaptchaServlet.doGet(CaptchaServlet.java:127)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.filters.ExpiresFilter.doFilter(ExpiresFilter.java:1175)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:190)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
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:745)
有关守则为:
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
HttpSession session = req.getSession();
Captcha captcha = getNumberCaptcha(_width, _height, 5, Color.black);
session.setAttribute(NAME, captcha);
resp.setHeader("Cache-Control", "private,no-cache,no-store");
resp.setContentType("image/png");
// See https://wiki.apache.org/tomcat/FAQ/KnownIssues#ImageIOIssues
// Wrap insite MyImageIOOutputStream
ImageIO.write(captcha.getImage(), "png", new MyImageIOOutputStream(resp.getOutputStream()));
resp.getOutputStream().flush();
resp.getOutputStream().close();
}
在开始说它是 ImageIO 之前,我们确实使用了 https://wiki.apache.org/tomcat/FAQ/KnownIssues#ImageIOIssues 上指定的 MyImageIOOutputStream。
我们甚至尝试将图像从 File 加载到字节数组中,并在共振中发送字节数组(因此没有使用 ImageIO),但问题仍然相同。
答:
令人惊讶的是,此错误发生在 Tomcat 7.0.61 中,但在 7.0.59 中却没有。该错误基本上表示您在发送 HTTP 响应标头后正在创建会话。这是一个问题,因为会话需要 cookie,并且 cookie 在 HTTP 响应标头中传输。所以现在发送cookie为时已晚。
假设 CaptchaServlet 是您的代码,最简单的解决方案是在 servlet 中写入任何输出之前创建会话 ()。然后,您可以安全地使用任何 servlet 容器。getSession()
评论
HttpSession session = req.getSession();
我确认我有和你一样的问题(在我的特殊情况下,7.0.62 vs 7.0.59)。如果 Tomcat 版本为 7.0.59,我的应用程序在 apache 代理后面工作正常,但如果我在代理后面使用 7.0.62,我的跟踪与您相同。
在我看来,我们应该尽快向Tomcat报告
评论