Tenho um PhaseListener que verifica se o usuário está logado, isso funciona tranquilo.
O problema é quando a sessão expira, ele não consegue redirecionar para a página de login
Alguém pode dar uma ajuda?
PhaseListener
@SuppressWarnings("serial")
public class Autorizador implements PhaseListener {
public static final String loginPage = "/login.jsp";
public void afterPhase(PhaseEvent event) {
FacesContext fc = event.getFacesContext();
if(fc.getViewRoot().getViewId().equals(loginPage)){
return;
}
ELResolver elr = fc.getApplication().getELResolver();
LoginHandler login = (LoginHandler) elr.getValue(fc.getELContext(), null, "loginHandler");
if(login == null || !login.isLogado()){
NavigationHandler nav = fc.getApplication().getNavigationHandler();
nav.handleNavigation(fc, null, "login");
}
}
public void beforePhase(PhaseEvent arg0) {
}
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
}
11:12:21,947 ERROR BaseXMLFilter:157 - Exception in the filter chain
javax.servlet.ServletException: viewId:/jsp/home.jsp - View /jsp/home.jsp could not be restored.
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:270)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:154)
at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:260)
at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:366)
at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:493)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Unknown Source)
Caused by: javax.faces.application.ViewExpiredException: viewId:/jsp/home.jsp - View /jsp/home.jsp could not be restored.
at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:186)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:104)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
... 18 more
Resolvido parcialmente.
Fiz um Filter para verificar quando a sessão expirou, ele consegue redirecionar para o login, e mantive este PhaseListener acima (agora AutorizadorPhaseListener) para verificar usuários.
O problema agora é que quando a sessão expira e é clicado em um botao com a tag <a4j: … o Filter não é chamado, sómente o PhaseListener, continuando com o mesmo problema descrito acima também.
O problema é o momento em que o PhaseListener é chamado, depois de RESTORE_VIEW. Minha sugestão é chamar o seu código antes dessa fase. Isso porque a exceção ocorre dentro dela.
Troque o método beforePhase para afterPhase e vice-versa e veja o que acontece.
Valeu pela ajuda, consegui resolver com a dica do Leonardo3001. Agora em qualquer ação ele verifica a sessão e retorna para o login caso esteja expirada ou usuário não logado.
Segue o código:
@SuppressWarnings("serial")
public class AutorizadorPhaseListener implements PhaseListener {
public static final String loginPage = "/login.jsp";
public void afterPhase(PhaseEvent event) {
try {
FacesContext fc = event.getFacesContext();
if(fc.getViewRoot().getViewId().equals(loginPage)){
return;
}
ELResolver elr = fc.getApplication().getELResolver();
LoginHandler login = (LoginHandler) elr.getValue(fc.getELContext(), null, "loginHandler");
if(login == null || !login.isLogado()){
NavigationHandler nav = fc.getApplication().getNavigationHandler();
nav.handleNavigation(fc, null, "login");
}
} catch (Exception e) {
// Não há necessidade de informar erro
}
}
public void beforePhase(PhaseEvent arg0) {
ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
HttpServletRequest request = (HttpServletRequest) context.getRequest();
if(!request.getRequestURL().toString().endsWith(loginPage) && context.getSession(false) == null){
try {
context.redirect(request.getContextPath() + "/faces" + loginPage);
} catch (IOException e) {
// Não há necessidade de informar erro
}
}
}
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
}