request.getSession(false) 导致 java.lang.IllegalStateException

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5831960/
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-10-30 13:01:07  来源:igfitidea点击:

request.getSession(false) causes java.lang.IllegalStateException

javatomcatservletstomcat6

提问by coder247

When I try to get the session from the request, it causes a null pointer exception if the session is expired. Given below is a part of the code. I get exception on the third line.

当我尝试从请求中获取会话时,如果会话过期,它会导致空指针异常。下面给出的是代码的一部分。我在第三行遇到异常。

public void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpReq = (HttpServletRequest) req;
HttpSession session = httpReq.getSession(false);

And here is the stacktrace :

这是堆栈跟踪:

java.lang.IllegalStateException: getLastAccessedTime: Session already invalidated
at org.apache.catalina.session.StandardSession.getLastAccessedTime(StandardSession.java:423)
at org.apache.catalina.session.StandardSessionFacade.getLastAccessedTime(StandardSessionFacade.java:84)
at com.myapp.admin.CustomerContext.valueUnbound(CustomerContext.java:806)
at org.apache.catalina.session.StandardSession.removeAttributeInternal(StandardSession.java:1686)
at org.apache.catalina.session.StandardSession.expire(StandardSession.java:801)
at org.apache.catalina.session.StandardSession.isValid(StandardSession.java:576)
at org.apache.catalina.connector.Request.doGetSession(Request.java:2386)
at org.apache.catalina.connector.Request.getSession(Request.java:2120)
at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:833)
at com.myapp.ui.web.filter.ApplicationSessionFilter.doFilter(ApplicationSessionFilter.java:45)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.myapp.ui.web.filter.ErrorFilter.doFilter(ErrorFilter.java:42)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:190)
at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:291)
at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:776)
at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:705)
at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:898)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:690)
at java.lang.Thread.run(Thread.java:662)

回答by kensen john

This is not a Nullpointer exception.
This is an Illegal state exception.

这不是空指针异常。
这是一个非法状态异常。

This occurs when the session has been invalidated/expired, and you try to access it.

当会话已失效/过期并且您尝试访问它时会发生这种情况。

Session gets invalidated as follows.

会话失效如下。

session.invalidate();

After invalidate is called, you cant use the session.

调用 invalidate 后,您不能使用会话。

Session expires when they timeout. After they expire, if you try to use it, it will throw the same exception.

会话在超时时到期。它们过期后,如果您尝试使用它,它将抛出相同的异常。

These are the ways you can manually set a timeout.

这些是您可以手动设置超时的方法。

set your timeout in web.xml. This is set in minutes.

在 web.xml 中设置超时。这是以分钟为单位设置的。

<session-config>
   <session-timeout>30</session-timeout> 
</session-config>

Or you can set it in in your java as well.

或者你也可以在你的java中设置它。

public void setMaxInactiveInterval(int interval)

session.setMaxInactiveInterval(30*60); // This we set in seconds. 

Here we specify the time, in seconds, between client requests before the servlet container will invalidate this session. A negative time indicates the session should never timeout.

在这里,我们指定在 servlet 容器使此会话无效之前客户端请求之间的时间(以秒为单位)。负时间表示会话不应超时。

Make sure the operation you are doing is not taking longer than the timeout time. Else you will have to reset the value.

确保您正在执行的操作不超过超时时间。否则,您将不得不重置该值。

EDIT:
It is not possible to recover from it in a clean manner. The session will get invalidated/unusable, and you will need to create a new session and repopulate data. Generally people are redirected to an alternate Error PAge instead of showing the Stack Trace. "Your session has expired. Please login again."

编辑:
不可能以干净的方式从中恢复。会话将失效/不可用,您将需要创建一个新会话并重新填充数据。通常人们会被重定向到另一个错误页面,而不是显示堆栈跟踪。“您的会话已过期。请重新登录。”

Use request.isRequestedSessionIdValid() to identify whether the session ID is still valid.

使用 request.isRequestedSessionIdValid() 来识别会话 ID 是否仍然有效。

HttpSession session =httpReg.getSession(false);
if( !request.isRequestedSessionIdValid() )
{
        //comes here when session is invalid.
        // redirect to a clean error page "Your session has expired. Please login again."
}

Another option is to use handle the IllegalExceptionState using try catch

另一种选择是使用 try catch 处理 IllegalExceptionState

HttpSession session =httpReg.getSession(false);
try
{
     if(session != null)
     { 
       Date date = new Date(session.getLastAccessedTime()); 
    }
}
catch( IllegalStateException ex )
{
      //comes here when session is invalid.
      // redirect to a clean error page "Your session has expired. Please login again."
}

Side Note: If you do have a process which is taking a long time to complete and sessions are timing out (ex: parsing really large data records ). You should consider taking them out of the web application, and use simple java to run them as a process.

旁注:如果您确实有一个需要很长时间才能完成的进程并且会话超时(例如:解析非常大的数据记录)。您应该考虑将它们从 Web 应用程序中移除,并使用简单的 java 将它们作为进程运行。

回答by Bozho

Your exception shows that you have invalidated the session, by calling .invalidate(), but are trying to use it. This is not possible.

您的异常表明您已通过调用 使会话无效.invalidate(),但正在尝试使用它。这不可能。

Whenever you invalidate()a session, don't use it anymore.

每当您invalidate()进行会话时,请不要再使用它。