2009-06-23 15 views
18

此问题与我的另一个问题“How to redirect to Login page when Session is expired in Java web application?”有关。下面是我想要做的事:在JBoss AS中运行的JSF Web应用程序处理'session expired'5

  1. 我已经运行在JBoss上AS 5
  2. 当用户处于非活动状态的JSF Web应用程序,比如15分钟,我需要注销用户和如果他在会话过期后尝试使用应用程序,则将其重定向到登录页面。
  3. 因此,如'JSF Logout and Redirect'所示,我已经实现了一个过滤器,用于检查会话过期条件并将用户重定向到session-timed-out.jsp页面(如果会话已过期)。
  4. 我已经在web.xml中的所有其他过滤器定义之上添加了SessionExpiryCheckFilter,这样我的会话过期检查将始终得到第一个命中。

现在到了挑战我面临。由于我使用的是JBoss AS,当会话过期时,JBoss会自动将我重定向到登录页面(请注意会话过期检查过滤器未被调用)。所以,在我登录后,我的SessionExpiryCheckFilter拦截了请求,并且它看到一个会话可用。但是,它会抛出异常javax.faces.application.ViewExpiredException: viewId:/mypage.faces - View /mypage.faces could not be restored.

有没有人遇到过这个问题?任何想法来解决这个问题?

+0

您使用的是Seam吗? – 2009-06-23 10:14:05

+0

不,我不使用Seam。 – Veera 2009-06-23 11:04:21

回答

15

以下办法为我工作。请注意,您必须使用JSTL核心taglib重定向,而不是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" /> 

您也可以使用这种方法用于其他错误类型或例外。例如,该元件包含一个错误代码或异常类型和资源中的web应用程序的路径:

<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> 
3

如果您正在使用Mojarra/Sun RI,您可能需要尝试将其添加到您的网站。XML:

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

但是要知道,这并不总是完美的解决方案。它隐藏了用户失去了会话的事实。

1

实现javax.faces.event.PhaseListener在faces-config.xml中恢复视图

@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; 
} 

寄存器

0

我试图写它的过滤器,但它不是为我工作的一些如何,所以我做了一个 替代它。

我做到了,这样在每一个页面,我不希望用户无需登录访问:

<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(); 
     } 
} 

如果有一个会议,但没有人登录,然后它会带你到一个重定向页面。

相关问题