当我尝试从请求中获取会话时,如果会话过期,它将导致空指针异常。下面给出的是代码的一部分。我在第三行出现异常。
public void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException, ServletException { HttpServletRequest httpReq = (HttpServletRequest) req; HttpSession session = httpReq.getSession(false);
这是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)
这不是Nullpointer异常。 这是一个非法状态异常。
当会话无效/过期并且您尝试访问它时,会发生这种情况。
会话如下无效。
session.invalidate();
调用invalidate后,您将无法使用该会话。
会话在超时时过期。它们过期后,如果尝试使用它,它将抛出相同的异常。
这些是您可以手动设置超时的方法。
在web.xml中设置超时。以分钟为单位设置。
<session-config> <session-timeout>30</session-timeout> </session-config>
或者,您也可以在Java中进行设置。
public void setMaxInactiveInterval(int interval) session.setMaxInactiveInterval(30*60); // This we set in seconds.
在这里,我们指定客户端请求之间servlet容器使该会话无效之前的时间(以秒为单位)。时间为负数表示会话永不超时。
确保您正在执行的操作所花费的时间不超过超时时间。否则,您将不得不重置该值。
编辑: 不可能以干净的方式从中恢复。该会话将变为无效/不可用,您将需要创建一个新会话并重新填充数据。通常,人们被重定向到备用错误页面,而不是显示堆栈跟踪。“您的会话已过期。请重新登录。”
使用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." }
另一个选择是使用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." }
旁注:如果您确实有一个过程需要很长时间才能完成,并且会话正在超时(例如:解析非常大的数据记录)。您应该考虑将它们从Web应用程序中删除,并使用简单的Java将其作为进程运行。