2010-11-26 4 views
5

Suite à ma question précédente dans Creating FacesMessage in action method outside JSF conversion/validation mechanism?, j'essaie de gérer les exceptions levées à partir de la couche de gestion en dehors de mes beans gérés.JSF 2: Est-ce une bonne approche pour gérer les exceptions métier?

La stratégie consiste à rechercher et convertir des exceptions d'affaires aux messages de visages dans le PhaseListener.

Cela fonctionne comme je l'espérais, mais je me demandais juste si je ne faisais que réinventer la roue, ou le faire correctement avec le mauvais sens?

Voici mon exemple de code extrait:

public class BusinessExceptionHandler implements PhaseListener { 

    @Override 
    public void afterPhase(PhaseEvent phaseEvent) { 
     ExceptionHandler exceptionHandler = phaseEvent.getFacesContext().getExceptionHandler(); 

     // just debugging the handled exception, nothing here 
     /* 
     for (ExceptionQueuedEvent event : exceptionHandler.getHandledExceptionQueuedEvents()) { 
      ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource(); 
      System.out.println("handled exception : " + context.getException()); 
     }*/ 

     for (Iterator<ExceptionQueuedEvent> it = exceptionHandler.getUnhandledExceptionQueuedEvents().iterator(); 
       it.hasNext();) { 

      ExceptionQueuedEvent event = it.next(); 
      ExceptionQueuedEventContext eventContext = (ExceptionQueuedEventContext) event.getSource(); 
      Throwable e = eventContext.getException(); 
      System.out.println("unhandled exception : " + e); 

      // get the root cause exception 
      while (e.getCause() != null) { 
       e = e.getCause(); 
      } 

      System.out.println("cause exception : " + e + 
       ", cause exception is BE : " + (e instanceof BusinessException)); 

      // handle BE 
      if (e instanceof BusinessException) { 
       BusinessException be = (BusinessException) e; 
       System.out.println("processing BE " + be); 
       FacesMessage message = Messages.getMessage(
        "com.corejsf.errors", 
        be.getMessage(), 
        be.getParamValues() 
       ); 
       FacesContext context = FacesContext.getCurrentInstance(); 
       context.addMessage(null, message); 
       it.remove(); // remove the exception 

       // works fine without this block, if BE is thrown, always return to the original page 
       /* 
       NavigationHandler navigationHandler = context.getApplication().getNavigationHandler(); 
       System.out.println("navigating to " + context.getViewRoot().getViewId()); 
       navigationHandler.handleNavigation(context, context.getViewRoot().getViewId(), null); 
       */ 
      } 
     } 
    } 

    @Override 
    public void beforePhase(PhaseEvent phaseEvent) { 
    } 

    @Override 
    public PhaseId getPhaseId() { 
     return PhaseId.INVOKE_APPLICATION; 
    } 

} 

Merci!

Cordialement, Albert Kam

Répondre

2

Votre approche est un mélange des approches de traitement des exceptions JSF 1.x et JSF 2.x. Puisque vous utilisez JSF 2.x, je suggère une approche pure JSF 2.x sans PhaseListener et avec l'aide du nouveau ExceptionHandler API.

Vous pouvez trouver un exemple qui traite la ViewExpiredException à la page 282 du livre "JSF 2.0: The Complete Reference" qui est disponible en ligne here (cliquez sur le lien 1er résultat).

+0

Salut à nouveau. Merci pour l'idée. La page 282 n'est pas disponible. Mais après quelques recherches, j'ai trouvé l'article d'Edburn sur ce genre de sujet, et j'utiliserai cette pratique plus tard: http://weblogs.java.net/blog/edburns/archive/2009/09/03/dealing-gracefully-viewexpiredexception- jsf2 – bertie

3

Je ne sais pas pourquoi vous allez dans cette voie, la création et l'enregistrement de votre propre gestionnaire d'exception est vraiment facile. Bien que plus facile sera Seam Catch (http://seamframework.org/Seam3/CatchModule et http://docs.jboss.org/seam/3/catch/3.0.0.Alpha1/reference/en-US/html_single/). Je n'ai pas encore de bridge JSF, mais ce sera très facile à faire. Ensuite, tout ce que vous avez à faire est d'écrire une méthode qui va gérer une exception spécifique, et vous aurez terminé!

+0

Im encore nouveau à la FSJ et plein de doutes sur les meilleures pratiques, d'où la question ci-dessus :) Merci pour la suggestion, bien que je n'utilise pas le cadre de couture, je vais jeter un oeil sur le gestionnaire d'exception api. – bertie

Questions connexes