我们正在从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),但问题仍然存在。
答案 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报告