it-swarm.com.ru

Обработка "сеанса истекла" в веб-приложении JSF, работающем в JBoss AS 5

Этот вопрос связан с моим другим вопросом " Как перенаправить на страницу входа в систему, когда сеанс истек в веб-приложении Java? ". Вот что я пытаюсь сделать:

  1. У меня есть веб-приложение JSF, работающее на JBoss AS 5
  2. Когда пользователь неактивен, например, в течение 15 минут, мне нужно выйти из системы и перенаправить его на страницу входа, если он пытается использовать приложение после истечения сеанса.
  3. Итак, как было предложено в ' JSF Logout and Redirect ', я реализовал фильтр, который проверяет условие истечения сеанса и перенаправляет пользователя на страницу session-timed-out.jsp, если сеанс истек.
  4. Я добавил SessionExpiryCheckFilter поверх всех других определений фильтров в web.xml, чтобы моя проверка истечения сеанса всегда получала первое попадание.

Теперь идет вызов, с которым я сталкиваюсь. Поскольку я использую JBoss AS, когда сеанс истек, JBoss автоматически перенаправляет меня на страницу входа (обратите внимание, что фильтр проверки истечения сеанса не вызывается). Итак, после входа в систему мой SessionExpiryCheckFilter перехватывает запрос и видит, что сеанс доступен. Но он выдает исключение javax.faces.application.ViewExpiredException: viewId:/mypage.faces - View /mypage.faces could not be restored.

Кто-нибудь сталкивался с этой проблемой раньше? Есть идеи, чтобы решить эту проблему?

18
Veera

Следующий подход работает для меня. Обратите внимание, что вы должны использовать перенаправление taglib ядра JSTL, а не перенаправление jsp, чтобы это работало (так как срок действия jsp также истекает).

В вашемFacesConfig.xmlвы помещаете следующее:

<error-page>
    <exception-type>javax.faces.application.ViewExpiredException</exception-type>
    <location>/sessionExpired.jsf</location>
</error-page>

sessionExpired.jsp:

<%@page contentType="text/html" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib uri="http://Java.Sun.com/jsp/jstl/core" prefix="c" %>

<c:redirect url="/login.jsf" />

Вы также можете использовать этот подход для других типов ошибок или исключений. Например, элемент содержит отображение между кодом ошибки или типом исключения и путем к ресурсу в веб-приложении.

<error-page>
    <error-code>400</error-code>
    <location>/400.html</location>
</error-page>

или элемент содержит полное имя класса типа исключения Java.

<error-page>
    <exception-type>javax.servlet.ServletException</exception-type>
    <location>/servlet/ErrorDisplay</location>
</error-page>
15
Chris Dale

Если вы используете Mojarra/Sun RI, вы можете попробовать добавить это в ваш web.xml:

<context-param>
    <param-name>com.Sun.faces.enableRestoreView11Compatibility</param-name> 
    <param-value>true</param-value>
</context-param>

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

3
skytteren

Реализуйте javax.faces.event.PhaseListener для представления Восстановления

@Override
public void afterPhase(PhaseEvent event) {
    FacesContext facesContext = event.getFacesContext();
     if(facesContext.getViewRoot()==null){   
       try{   
           facesContext.getExternalContext().redirect(HOME_PAGE);   
           facesContext.responseComplete();   
       } catch (IOException e){   
           e.printStackTrace();   
       }   
     }
}

@Override
public void beforePhase(PhaseEvent event) {}

@Override
public PhaseId getPhaseId() {
    return PhaseId.RESTORE_VIEW;
}

зарегистрироваться в лица-config.xml

1
keith

Я попытался написать фильтр для него, но кое-что, как он не работал для меня, поэтому я сделал для него альтернативу

Я делал это на всех страницах, к которым пользователь не должен заходить без входа в систему: 

<f:view>
    <h:dataTable value="#{userHome.validuser()}"/>
     // my code
<f:view/>

Это вызовет функцию validuser(), которая находится в моем управляемом сессионном компоненте.

Теперь это моя функция. Во время входа в систему я уже вставляю объект пользователя в сеанс.

public void validuser()
{
     FacesContext context = FacesContext.getCurrentInstance();
    UserLogin ul = (UserLogin) context.getExternalContext().getSessionMap().get("userbean");

     if (ul == null)
         try{
                context.getExternalContext().redirect("/HIBJSF/faces/LoginPage.xhtml");
                context.responseComplete();
        }
         catch (IOException e)
        {
         e.printStackTrace();
        }
} 

Если есть сеанс, но никто не вошел в систему, то вы попадете на страницу перенаправления.

0
ifti

Я бы предложил написать слушатель сессии вместе с фильтром.

Когда сеанс истекает, вы можете создать новый объект сеанса и установить значение времени ожидания для нового объекта. 

Просто проверьте значение таймаута в фильтре и перенаправьте браузер.

Смотрите http://www.Java2s.com/Code/Java/Servlets/Servletsessionlistener.htm

0
Koekiebox