将tomcat 7.0.59升级到7.0.61:在提交响应后无法创建会话

时间:2015-10-11 11:03:23

标签: java session tomcat

我们正在从Tomcat 7.0.59升级到7.0.61并收到以下错误。

仅当通过Apache代理(无SSL)传递时才会发生此错误。

从浏览器调用Tomcat上下文(没有Apache代理)时,它可以正常工作。

有没有人遇到过相同/类似的问题?

我们确实浏览了更改日志(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),但问题仍然存在。

2 个答案:

答案 0 :(得分:0)

令人惊讶的是,发现此错误发生在Tomcat 7.0.61中,而不是发生在7.0.59中。该错误基本上表示您在发送HTTP响应的标头后创建会话。这是一个问题,因为会话需要cookie,并且cookie在HTTP响应头中传输。所以发送cookie已经太晚了。

假设CaptchaServlet是您的代码,最简单的解决方案是在您编写servlet中的任何输出之前创建会话(getSession())。然后,您可以安全地使用任何servlet容器。

答案 1 :(得分:0)

我确认我遇到了与你相同的问题(在我的特定情况下,7.0.62 vs 7.0.59)。如果Tomcat版本是7.0.59,我的应用程序在apache代理后面工作正常,但如果我在代理后面使用7.0.62,我的跟踪相同。

在我看来,我们应该尽快向Tomcat报告