Spring java.lang.IllegalStateException:提交响应后无法创建会话

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26343666/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 02:17:45  来源:igfitidea点击:

Spring java.lang.IllegalStateException: Cannot create a session after the response has been committed

javaspringsessionspring-mvcspring-security

提问by RanPaul

I am having a session management issue in my spring application, here is the scenario. When a user opens my app URL it'll ask for credentials and logs in. After the user looged in and if he open a new tab and paste my app URL it'll ask for credentials again and user logs in.

我的 spring 应用程序中存在会话管理问题,这是场景。当用户打开我的应用程序 URL 时,它会要求提供凭据并登录。在用户登录后,如果他打开一个新选项卡并粘贴我的应用程序 URL,它会再次要求提供凭据并用户登录。

Now if the user logs out in tab1 and if user wants to performs any operation in second tab user gets an error with below stacktrace and logs out.

现在,如果用户在 tab1 中注销,并且用户想要在第二个选项卡中执行任何操作,则用户会收到以下堆栈跟踪的错误并注销。

Oct 10, 2014 3:11:27 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [CollPortal] in context with path [/CollPortal] threw exception
java.lang.IllegalStateException: Cannot create a session after the response has been committed
    at org.apache.catalina.connector.Request.doGetSession(Request.java:2886)
    at org.apache.catalina.connector.Request.getSession(Request.java:2316)
    at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:898)
    at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:910)
    at com.dc.core.common.FlashRecyclingFilter.doFilterInternal(FlashRecyclingFilter.java:22)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at com.dc.core.common.StripJSessionIdFilter.doFilter(StripJSessionIdFilter.java:101)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:722)

Here is my FlashRecyclingFilter

这是我的 FlashRecyclingFilter

@Component
public class FlashRecyclingFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
        throws ServletException, IOException {
    super.doFilter(request, response, filterChain);
    IFlash flash = new Flash(request.getSession());
    flash.recycle();
    }
}

How do I make sure user should be able to perform operations in one tab when the user is logged out in another tab? Can anyone please help me with my issue?

当用户在另一个选项卡中注销时,如何确保用户应该能够在一个选项卡中执行操作?任何人都可以帮我解决我的问题吗?

采纳答案by Pavel Horal

What happens is that Spring probably sends redirect to the login page, while your custom filter tries to create session (which can not be done as the response has been already sent).

发生的情况是 Spring 可能将重定向发送到登录页面,而您的自定义过滤器尝试创建会话(由于响应已经发送,因此无法完成)。

You should modify your filter so that it does not eagerly create the session on its own:

您应该修改过滤器,使其不会急切地自行创建会话:

super.doFilter(request, response, filterChain);
HttpSession session = request.getSession(false);
if (session != null) {
    IFlash flash = new Flash(session);
    flash.recycle();
}

回答by Sandeep Reddy

Check whether you have used the rd.forward() or rd.include(). we have to use rd.include() to resolve that error. try with that once.

检查您是否使用了 rd.forward() 或 rd.include()。我们必须使用 rd.include() 来解决该错误。尝试一次。