我有三个JSF2.0Web模块,当会话到期时,我需要重定向到登录页面。
我尝试过使用HttpSessionListener,它调用了sessionDestroyed()事件方法,但我无法转发/重定向其中的请求。我认为这是因为没有HttpServletRequest和HttpServletResponse对象。
我也尝试过使用PhaseListener,但它在the浏览器中导致了“重定向次数过多”错误。
public class SessionListener implements PhaseListener {
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
public void beforePhase(PhaseEvent event) {
if (!FacesContext.getCurrentInstance().isPostback()) {
try {
System.out.println("Session Destroyed");
FacesContext.getCurrentInstance().getExternalContext().redirect("login.jsf");
}
catch (Exception e) {
System.out.println("error" + e);
}
}
}
public void afterPhase(PhaseEvent event) {
try {
System.out.println("Session Created");
}
catch (Exception e) {
System.out.println("error" + e);
}
}
}为什么这些尝试不起作用,我如何才能最好地解决它?
发布于 2012-06-08 22:25:11
在会话到期的时刻发送重定向是不可能的()。也就是说,客户端此时没有发送任何HTTP请求,您可以使用重定向进行响应。
您应该只保留现有的身份验证机制,当用户不再登录时,该机制将重定向到登录页面。您最多只能通过检查用户是否因为会话已过期或只是因为他以前从未登录过(即这是一个新的请求)而被重定向到登录页面来改进它。
如果HttpServletRequest#getRequestedSessionId()没有返回null (这意味着客户端已经发送了一个会话cookie,因此假定会话仍然有效),而HttpServletRequest#isRequestedSessionIdValid()返回false (这意味着该会话在服务器端已经过期),则可以检查这一点。您可以在检查登录用户的筛选器中执行此操作(您已经有了一个,对吧?或者您正在使用容器管理的身份验证?)
User user = (User) session.getAttribute("user");
if (user == null) {
String loginURL = request.getContextPath() + "/login.jsf";
if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) {
response.sendRedirect(loginURL + "?expired=true");
} else {
response.sendRedirect(loginURL);
}
} else {
chain.doFilter(request, response);
}然后在login.xhtml页面中检查它
<h:panelGroup rendered="#{param.expired}">
<p>You have been redirected to the login page, because your session was expired.</p>
</h:panelGroup>顺便说一下,您的阶段侦听器方法没有任何意义。它确实会在每个请求上发送一个重定向,导致它在无限循环中运行。还原视图阶段与会话到期完全无关。
发布于 2012-06-08 13:54:48
试着使用
FacesContext.getCurrentInstance().getApplication().getNavigationHandler().
handleNavigation(context, null, "LoginForm");但请注意,您应该使用Servlet过滤器来实现这些目的,最好不要从PhaseListener进行任何重定向,因为这样很容易出错。
https://stackoverflow.com/questions/10943016
复制相似问题