java - Manejo de ''sesión caducada'' en la aplicación web JSF, ejecutándose en JBoss AS 5
session servlet-filters (5)
Esta pregunta ya tiene una respuesta aquí:
Esta pregunta está relacionada con mi otra pregunta " ¿Cómo redireccionar a la página de inicio de sesión cuando la sesión caduca en la aplicación web de Java? ". A continuación es lo que estoy tratando de hacer:
- Tengo una aplicación web JSF que se ejecuta en JBoss AS 5
- Cuando el usuario está inactivo durante, digamos, 15 minutos, necesito cerrar la sesión del usuario y redirigirlo a la página de inicio de sesión, si está tratando de usar la aplicación después de que la sesión haya expirado.
- Entonces, como se sugirió en '' JSF Logout and Redirect '', implementé un filtro que verifica la condición de expiración de la sesión y redirige al usuario a una página session-timed-out.jsp, si la sesión ha expirado.
- He agregado SessionExpiryCheckFilter encima de todas las demás definiciones de filtro en web.xml, de modo que la verificación de caducidad de mi sesión siempre obtenga el primer hit.
Ahora viene el desafío que estoy enfrentando . Dado que estoy usando JBoss AS, cuando la sesión expiró, JBoss me redirige automáticamente a la página de inicio de sesión (tenga en cuenta que no se invoca el filtro de verificación de expiración de la sesión). Entonces, después de iniciar sesión, mi SessionExpiryCheckFilter intercepta la solicitud y ve que hay una sesión disponible. Pero, lanza la excepción javax.faces.application.ViewExpiredException: viewId:/mypage.faces - View /mypage.faces could not be restored.
¿Alguien ha enfrentado este problema antes? ¿Alguna idea para resolver este problema?
El siguiente enfoque funciona para mí. Tenga en cuenta que tiene que usar el redireccionamiento de etiquetas de núcleo JSTL y no el redireccionamiento jsp para que esto funcione (ya que también expira el jsp).
En tu FacesConfig.xml pones lo siguiente:
<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" />
También puede utilizar este enfoque para otros tipos de errores o excepciones. Por ejemplo, el elemento contiene una asignación entre un código de error o un tipo de excepción y la ruta de un recurso en la aplicación web .:
<error-page>
<error-code>400</error-code>
<location>/400.html</location>
</error-page>
o elemento contiene un nombre de clase completo de un tipo de excepción de Java.
<error-page>
<exception-type>javax.servlet.ServletException</exception-type>
<location>/servlet/ErrorDisplay</location>
</error-page>
Implementar javax.faces.event.PhaseListener para la vista de restauración
@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;
}
registrarse en faces-config.xml
Si está utilizando Mojarra / Sun RI puede intentar agregar esto a su web.xml:
<context-param>
<param-name>com.sun.faces.enableRestoreView11Compatibility</param-name>
<param-value>true</param-value>
</context-param>
Sin embargo, ten en cuenta que esta no es siempre la solución perfecta. Oculta el hecho de que el usuario ha perdido su sesión.
Sugeriría escribir un oyente de sesión junto con el filtro.
Cuando la sesión expira, puede crear un nuevo objeto de sesión y establecer un valor de tiempo de espera en el nuevo objeto.
Simplemente verifique el valor del tiempo de espera en el filtro y redirija el navegador.
Consulte http://www.java2s.com/Code/Java/Servlets/Servletsessionlistener.htm
Traté de escribir un filtro para él, pero de alguna manera no funcionó para mí, así que hice un alternativo para él.
Lo hice así en todas las páginas a las que no quiero que acceda el usuario sin iniciar sesión:
<f:view>
<h:dataTable value="#{userHome.validuser()}"/>
// my code
<f:view/>
Esto llamará a la función validuser()
que está en mi bean administrado de sesión.
Ahora esta es mi función. Durante el inicio de sesión ya inserto el objeto de usuario en la sesión.
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();
}
}
Si hay una sesión pero nadie ha iniciado sesión, entonces lo llevará a una página de redireccionamiento.