quarta-feira, 26 de agosto de 2009

Implementando página de erro com JSF

Algumas pessoas estão tendo dúvidas sobre como implementar uma página de erro com JSF, e resolvi então criar este post para explicar uma maneira de implementar.

Para se realizar o redirecionamento pode se utilizar o ActionListener do JSF. Segue abaixo um exemplo de implementação da classe deste ActionListener:


/**
* Classe responsável por tratar erros inesperados do sistema.
*
* @author Samuel Delfim
*
*/
public class ExceptionHandler extends ActionListenerImpl {

@Override
public void processAction(ActionEvent event) {
// Obtem o contexto JSF
FacesContext context = FacesContext.getCurrentInstance();

try {
// Executa o método da classe Pai
super.processAction(event);

} catch (Exception e) {

// Se ocorrer um erro inesperado, exibe a mensagem abaixo
context.addMessage(null, new FacesMessage(
FacesMessage.SEVERITY_FATAL, e.getMessage(), null));


// Redireciona para a pagina com o mapeamento 'erro'
// no faces-config.
context.getApplication().getNavigationHandler().
handleNavigation(context, null, "erro");
}
}
}


Pode-se, por exemplo, na classe acima realizar tratamentos diferentes para cada tipo de exceção.

Para aplicar o Listener em uma aplicação jsf deve ser colocado o seguinte trecho dentro do arquivo faces-config.xml:


<application>
<!-- Aplicação do Listener -->
<action-listener>com.thinkworks.handler.exception.ExceptionHandler
</action-listener>
<view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
<locale-config>
<default-locale>pt_BR</default-locale>
<supported-locale>pt_BR</supported-locale>
<supported-locale>es_AR</supported-locale>
</locale-config>
<message-bundle>com.bionexo.mensagens.Mensagens</message-bundle>
</application>


O trecho a ser copiado se refere à tag e deve ser aplicado ao view-handler específico. Neste caso, o ViewHandler utilizado é o do projeto facelets que está sendo utilizado no projeto em questão.

Também no arquivo faces-config.xml deve ser realizado o mapeamento da página de erro.
Segue abaixo um exemplo de mapeamento de página de erro:


<navigation-rule>
<navigation-case>
<from-outcome>erro</from-outcome>
<to-view-id>/pages/erro/paginaErro.xhtml</to-view-id>
</navigation-case>
</navigation-rule>


É isto aí pessoal. Espero ter ajudado...

2 comentários:

Rafael Ponte disse...

Infelizmente a especificação do Jsf1.2 não disponibiliza uma solução padrão para este problema. Se não me engano a versão 2.0 já tem isso resolvido.

Tua solução foi muito bem explanada, de uma maneira clara e objetiva. Parabéns. Somente faltou comentar que este handler só funcionaria para exceções lançadas de ActionListeners. Ou seja, no caso de Actions (que efetuam navegação dinamicamente) isso não serviria.

Enfim, excelente post. Parabéns.

Unknown disse...

Parabéns pelo post! Muito bem explicado.

Porém, me deparei com o problema descrito pelo Rafael Ponte.

Como seria a implementação para o caso das exceções que não são lançadas de ActionListeners? exibindo o stacktrace da exceção na página de erro.