Обработка "сеанса истек" в веб-приложении JSF, работающем в JBoss AS 5
Этот вопрос связан с моим другим вопросом "Как перенаправить на страницу входа, когда срок действия сессии истек в веб-приложении Java?". Ниже я пытаюсь сделать следующее:
- У меня есть веб-приложение JSF, работающее на JBoss AS 5
- Когда пользователь неактивен, скажем, 15 минут, мне нужно выйти из системы и перенаправить его на страницу входа в систему, если он пытается использовать приложение после истечения срока действия сессии.
- Итак, как было предложено в JSF Logout and Redirect ', я внедрил фильтр, который проверяет условие с истекшим сроком сессии и перенаправляет пользователь на странице session-timed-out.jsp, если сеанс истек.
- Я добавил SessionExpiryCheckFilter поверх всех других определений фильтров в web.xml, так что проверка срока действия моего сеанса всегда будет иметь первый хит.
Теперь идет вызов , с которым я сталкиваюсь. Поскольку я использую JBoss AS, когда сеанс истек, JBoss автоматически перенаправляет меня на страницу входа (обратите внимание, что фильтр проверки истечения срока действия сеанса не вызывается). Итак, после входа в систему мой SessionExpiryCheckFilter перехватывает запрос, и он видит, что сеанс доступен. Но это исключает исключение javax.faces.application.ViewExpiredException: viewId:/mypage.faces - View /mypage.faces could not be restored.
Кто-нибудь сталкивался с этой проблемой раньше? Любые идеи для решения этой проблемы?
Ответы
Ответ 1
Для меня работает следующий подход. Обратите внимание, что вам нужно использовать перенаправление основного теглиба 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>
Ответ 2
Если вы используете Mojarra/Sun RI, вы можете попробовать добавить это в свой web.xml:
<context-param>
<param-name>com.sun.faces.enableRestoreView11Compatibility</param-name>
<param-value>true</param-value>
</context-param>
Однако имейте в виду, что это не всегда идеальное решение. Это скрывает тот факт, что пользователь потерял сессию.
Ответ 3
Внедрение 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;
}
зарегистрировать в faces-config.xml
Ответ 4
Я бы предложил написать сессионный прослушиватель в сочетании с фильтром.
По окончании сеанса вы можете создать новый объект сеанса и установить значение таймаута для нового объекта.
Просто проверьте значение тайм-аута в фильтре и перенаправьте браузер.
См. http://www.java2s.com/Code/Java/Servlets/Servletsessionlistener.htm
Ответ 5
Я попытался написать фильтр для него, но некоторые, как он не работал у меня, поэтому я сделал
альтернативный для него.
Я сделал это так на каждой странице, что я не хочу, чтобы пользователь имел доступ без Логин:
<f:view>
<h:dataTable value="#{userHome.validuser()}"/>
// my code
<f:view/>
Это вызовет функцию validuser()
, которая находится в моем сеансе, управляемом bean.
Теперь это моя функция.
Во время входа в систему я уже вставляю объект пользователя в сеанс.
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();
}
}
Если есть сеанс, но никто не вошел в систему, он перенесет вас на страницу переадресации.