web-dev-qa-db-fra.com

Gestion de 'session expirée' dans l'application Web JSF, s'exécutant dans JBoss AS 5

Cette question est liée à mon autre question " Comment rediriger vers la page de connexion lorsque la session a expiré dans une application Web Java? ". Voici ce que j'essaie de faire:

  1. J'ai une application Web JSF s'exécutant sur JBoss AS 5
  2. Lorsque l'utilisateur est inactif pendant, disons, 15 minutes, je dois le déconnecter et le rediriger vers la page de connexion, s'il tente d'utiliser l'application après l'expiration de la session.
  3. Ainsi, comme suggéré dans ' JSF Logout and Redirect ', j'ai mis en place un filtre qui vérifie la condition d'expiration de session et redirige l'utilisateur vers une page session-timed-out.jsp, si la session a expiré.
  4. J'ai ajouté SessionExpiryCheckFilter au-dessus de toutes les autres définitions de filtre dans web.xml, afin que mon contrôle d'expiration de session obtienne toujours le premier résultat.

Maintenant vient le défi auquel je suis confronté . Étant donné que j'utilise JBoss AS, lorsque la session a expiré, JBoss me redirige automatiquement vers la page de connexion (notez que le filtre de vérification de l'expiration de la session n'est pas appelé). Donc, après ma connexion, SessionExpiryCheckFilter intercepte la demande et constate qu'une session est disponible. Mais, il lève l'exception javax.faces.application.ViewExpiredException: viewId:/mypage.faces - View /mypage.faces could not be restored.

Est-ce que quelqu'un a déjà fait face à ce problème? Des idées pour résoudre ce problème?

18
Veera

L'approche suivante fonctionne pour moi. Notez que vous devez utiliser la redirection JSTL core taglib et non la redirection jsp pour que cela fonctionne (car le jsp expire également).

Dans votre FacesConfig.xml vous mettez ce qui suit:

<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" />

Vous pouvez également utiliser cette approche pour d'autres types d'erreur ou exceptions. Par exemple, l'élément contient un mappage entre un code d'erreur ou un type d'exception et le chemin d'une ressource dans l'application Web:

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

ou element contient un nom de classe complet d'un type d'exception Java.

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

Si vous utilisez Mojarra/Sun RI, vous pouvez essayer d’ajouter ceci à votre fichier web.xml:

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

Cependant, sachez que ce n'est pas toujours la solution parfaite. Il cache le fait que l'utilisateur a perdu sa session.

3
skytteren

Implémenter la vue javax.faces.event.PhaseListener for Restore

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

s'inscrire dans faces-config.xml

1
keith

J'ai essayé d'écrire un filtre pour le filtre, mais certains ont montré que cela ne fonctionnait pas pour moi.

Je l'ai fait comme ceci dans chaque page à laquelle je ne veux pas que l'utilisateur accède sans login:

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

Cela appellera la fonction validuser() qui se trouve dans mon bean géré par session.

Maintenant c'est ma fonction. Lors de la connexion, j'ai déjà inséré l'objet utilisateur dans la session.

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

S'il existe une session mais que personne ne s'est connecté, cela vous mènera à une page de redirection.

0
ifti

Je suggérerais d'écrire un auditeur de session en conjonction avec le filtre.

Lorsque la session expire, vous pouvez créer un nouvel objet de session et définir une valeur de délai d'expiration pour le nouvel objet.

Il suffit de vérifier la valeur de délai dans le filtre et de rediriger le navigateur.

Voir http://www.Java2s.com/Code/Java/Servlets/Servletsessionlistener.htm

0
Koekiebox