2011-04-29 39 views
4

當我嘗試從請求中獲取會話時,如果會話過期,會導致空指針異常。下面給出的是代碼的一部分。我在第三行得到例外。request.getSession(false)會導致java.lang.IllegalStateException

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

這裏是堆棧跟蹤:

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) 
+0

可能沒有任何會話附加到他的請求。因爲如果您沒有創建任何會話,getSession(fasle)將返回null。 – Ankit 2011-04-29 12:26:40

+0

我們使用tomcat 6.0 – coder247 2011-04-29 12:26:57

+2

顯示整個堆棧跟蹤 – Bozho 2011-04-29 12:40:02

回答

8

這不是一個空指針異常。
這是一個非法狀態異常。

這會在會話失效/失效時發生,並且您嘗試訪問它。

會話失效如下。

session.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." 
} 

另一種選擇是使用通過嘗試捕捉

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." 
} 

旁註處理IllegalExceptionState: 如果你確實有其花費很長的時間來完成,會話超時的過程(如:解析真正的大數據記錄)。 你應該考慮將它們帶出Web應用程序,並使用簡單的Java將它們作爲一個進程運行。

+0

感謝您的評論..但我總是檢查之前使用會話空。從日誌中我可以看到第3行的異常原因。 – coder247 2011-04-29 12:50:25

+0

@ coder247,請你可以發佈整個堆棧跟蹤。 – 2011-04-29 12:55:42

+0

@code247,這可能是無關緊要的,但出於好奇,這一行會發生什麼? com.myapp.admin.CustomerContext.valueUnbound(CustomerContext.java:806) – 2011-04-29 13:08:16

2

您的異常顯示您已通過調用.invalidate()使會話失效,但正在嘗試使用它。這不可能。

無論何時你invalidate()一個會話,不要再使用它了。

相關問題