Senhores, desenvolvi uma aplicação com Eclipse, Tomcat7, JSF2 e PrimeFaces3. Está funcionando muito bem mas uma coisa me incomoda. Sempre que a session termina e tento abrir uma página, recebo um erro tipo:
HTTP Status 500 -
type Exception report
description The server encountered an internal error () that prevented it from fulfilling this request.
exception
javax.servlet.ServletException
javax.faces.webapp.FacesServlet.service(FacesServlet.java:606
root cause
java.lang.StackOverflowError
java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:768)
Isso é muito chato. O cliente vai entender nada, né?
Já tentei de todas as formas redirecionar o usuário para a tela de login, mas não funciona. Já li e tente implementar código com PhaseListener. E também não funcionou, talvez por erro meu que sou novo em JSF e ainda não entendi certos tópicos.
Em resumo, alguém pode me ajudar a evitar essa tela cheia de linhas de erros tomcat e fazer um redirecionamento decente para um tela de (Re) login?
Um abraço
usa isso no web.xml :
<error-page>
<error-code>500</error-code>
<location>/suapagina.jsf</location>
</error-page>
Caramba, Polverini! Quase! Está faltando pouco. Estou lutando com o erro que apareceu:
viewId:/views/ppgLogin.jsf - A exibição de /views/ppgLogin.jsf não pôde ser restaurada.]
with root cause
javax.faces.application.ViewExpiredException: viewId:/views/ppgLogin.jsf - A exibição de /views/ppgLogin.jsf não pôde ser restaurada.
Tem alguma idéia?
Um abraço
tira o error page 500 e joga esse aqui:
<error-page>
<exception-type>javax.servlet.ServletException</exception-type>
<location>/index.jsp</location>
</error-page>
Polverini, obrigadão pelo apoio. Quando fiz a troca, recebi o erro:
java.lang.StackOverflowError
org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:894)
OK.
Continuando a pesquisa, (entenda, goolgando a doidado… rs…), vi a dica:
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
no web.xml.
Coloquei e funcionou! Ficou assim:
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<error-page>
<error-code>500</error-code>
<location>/index1.jsf</location>
</error-page>
O que você acha? vale a salvar o estado no cliente ao inves de fazê-lo no servidor?
Abraços
quanto salvar o estado em server ou cliente te indico esse link:
http://www.rponte.com.br/2007/10/14/state_saving_method-server-ou-client/
eu faço da seguinte forma:
Tenho um phaselistener que pega a sessao (se nao existir ele cria) e procura um atributo (ex. id), caso nao exista o atributo eu faço um forward para a tela de login, desta forma quando ele enviar o cliente para tela de login já existira uma sessão nova criada.
Quando a redirect e forward tbm indico algumas informações do rpontes que é show de bola:
http://www.rponte.com.br/2008/07/12/repitam-comigo-redirect-nao-e-forward/
se der depois posta ai como deixou as configurações e o pq !!
Abraço
Polverini, pelo menos neste primeiro momento, deixarei assim como funcionou. Testei outras soluções mas sempre há um erro. Seja de stack, seja de view ViewExpiredException… Assim ao menos funciona. Valeu pela ajuda. Obrigado mesmo.
Boa noite e que Ele ilumine a nossa semana.
Abraços
bem, senhores, no fim ficou assim:
[code]public class AutorizaListener implements PhaseListener {
public void afterPhase(PhaseEvent event) {
FacesContext contexto = event.getFacesContext();// Obtém o contexto atual
String paginaAtual = contexto.getViewRoot().getViewId();// Obtém a página que atualmente está interagindo com o ciclo
boolean isLoginPage = paginaAtual.lastIndexOf("pgLogin.xhtml") > -1; // Se for a página 'login.jsp' seta a variável como true
HttpSession sessao = (HttpSession) contexto.getExternalContext().getSession(true);// Obtém a sessão atual
usuarioBean usuario = (usuarioBean) sessao.getAttribute("USER_OK");// Restaga o nome do usuário logado
if (!isLoginPage && usuario == null) {
// Redireciona o fluxo para a página de login
NavigationHandler nh = contexto.getApplication().getNavigationHandler();
nh.handleNavigation(contexto, null, "logout");
}
}
public void beforePhase(PhaseEvent event) {
}
public PhaseId getPhaseId() {
return PhaseId.RENDER_RESPONSE;
}
}[/code]
no faces-config:
<lifecycle>
<phase-listener>slv.com.actions.AutorizaListener</phase-listener>
</lifecycle>
<navigation-rule>
<from-view-id>*</from-view-id>
<navigation-case>
<from-outcome>logout</from-outcome>
<to-view-id>/views/pgLogin.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
no web.xml:
<error-page>
<location>/views/pgLogin.jsf?faces-redirect=true</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/views/pgLogin.jsf?faces-redirect=true</location>
</error-page>
Funcionou direitinho. Quando termina a sessão e o usuário tenta abrir uma página, ele é redirecionado para a página de login.
O único efeito colateral é que, na tela de (re) login, o usuário tem clicar duas vezes no botão login… rs… Fazer o quê, né?..
Um abraço e obrigado a todos que me auxiliaram nesta.