request.getSession (false) вызывает исключение java.lang.IllegalStateException - PullRequest
4 голосов
/ 29 апреля 2011

Когда я пытаюсь получить сеанс из запроса, это вызывает исключение нулевого указателя, если сеанс истек.Ниже приведена часть кода.Я получаю исключение на третьей строке.

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)

Ответы [ 2 ]

8 голосов
/ 29 апреля 2011

Это не исключение 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. 

Здесь мы указываем время в секундах между клиентскими запросами, прежде чем контейнер сервлета аннулирует этот сеанс. Отрицательное время означает, что сеанс никогда не должен прерываться.

Убедитесь, что выполняемая операция не занимает больше времени, чем время ожидания. В противном случае вам придется сбросить значение.

EDIT:
Невозможно восстановить его чистым способом. Сеанс будет признан недействительным / непригодным для использования, и вам нужно будет создать новый сеанс и повторно заполнить данные. Обычно люди перенаправляются на альтернативную страницу ошибок вместо отображения трассировки стека. «Ваша сессия истекла. Пожалуйста, войдите снова.»

Используйте 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."
}

Другой вариант - использовать дескриптор IllegalExceptionState с помощью try catch

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

Боковое примечание: Если у вас есть процесс, выполнение которого занимает много времени, а время сеансов истекает (например: анализ действительно больших записей данных). Вам следует рассмотреть возможность удаления их из веб-приложения и использовать простой Java для запуска их как процесса.

2 голосов
/ 29 апреля 2011

Ваше исключение показывает, что вы аннулировали сеанс, вызвав .invalidate(), но пытаетесь его использовать. Это невозможно.

Всякий раз, когда вы invalidate() проводите сеанс, больше не используйте его.

...