Olá pessoal,
Quando minha aplicação lança uma exceção não estou conseguindo realizar o redirecionamento para uma página de erro.
O interessante é que eu já estou conseguindo realizar o redirecionamento p/ erros como “página não encontrada” (erro 404) e “permissão negada” (erro 403). Estes estão funcionando perfeitamente.
Queria que, ao receber uma exceção, esta não fosse mostrada na tela, e sim houvesse um redirecionamento para uma página de erro.
Estou realizando um teste e estou tendo a seguinte exceção “javax.el.PropertyNotFoundException” a qual está sendo jogada na tela (ou seja, o redirecionamento não funciona para ela).
Utilizo JSF 1.2 + Richfaces 3.3.3 + Spring 3
Abaixo vai o meu arquivo web.xml:
<error-page>
<exception-type>java.lang.SecurityException</exception-type>
<location>/pages/loginEx.jsf</location>
</error-page>
<error-page>
<error-code>403</error-code>
<location>/pages/error/redirect-forbidden.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/pages/error/redirect-notfound.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/pages/error/redirect-error.jsp</location>
</error-page>
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/pages/error/redirect-error.jsp</location>
</error-page>
Depois de várias tentativas consegui resolver meu problema.
Customizei o FaceletViewHandler que é uma das classes declaradas no arquivo faces-config.xml.
Para isso, criei uma classe CustomViewHandler que herda de FaceletViewHandler e apenas redefini o método “handleRenderException”.
Após criar a classe apenas adicionei o CustomViewHandler no lugar do FaceletViewHandler no arquivo faces-config.xml.
A classe fica assim:
import java.io.IOException;
import java.util.Map;
import java.util.logging.Level;
import javax.faces.application.ViewHandler;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletResponse;
import com.sun.facelets.FaceletViewHandler;
public class CustomViewHandler extends FaceletViewHandler {
public CustomViewHandler(ViewHandler parent) {
super(parent);
}
@Override
protected void handleRenderException(FacesContext context, Exception ex) {
try {
log.log(Level.SEVERE, ex.toString());
ex.printStackTrace();
getSessionMap().put("GLOBAL_ERROR", ex);
String contextPath = FacesContext.getCurrentInstance().getExternalContext().getRequestContextPath();
getHttpResponseObject().sendRedirect(contextPath+"/pages/error/redirect-error.jsp");
} catch (IOException e) {
log.log(Level.SEVERE,"Couldn't redirect to error page", e);
}
}
private HttpServletResponse getHttpResponseObject() {
return (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
}
private Map<String, Object> getSessionMap() {
return FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
}
}
No faces-config.xml fica assim:
<view-handler>pacote.CustomViewHandler</view-handler>
No meu caso ainda tive outro problema. Após a implementação desta classe apareceu o seguinte erro :" The type javax.el.ELException cannot be resolved. It is indirectly referenced from required .class files "
Para resolve-lo é simples, basta ir nas propriedades do seu projeto, navegar para “Targeted Runtimes” e marcar o seu servidor.