2010-11-26 1 views
5

私の以前の質問Creating FacesMessage in action method outside JSF conversion/validation mechanism?に続いて、私はマネージドBeanの外でビジネスレイヤーからスローされた例外を処理しようとしています。JSF 2:これはビジネス例外を処理するための良いアプローチですか?

戦略は、Business例外を検索し、PhaseListener内のfacesメッセージに変換することです。

私は期待通りに働いていますが、私はちょうど車輪を再発明しているのか、間違った方法で正しいことをしているのだろうかと思っています。ここで

は私のサンプルコードスニペットです:

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; 
    } 

} 

ありがとうございました!

よろしく、 アルバート・カム

答えて

2

あなたのアプローチは、JSF 1.xとJSF 2.xの例外処理方法の混在です。 JSF 2.xを使用しているので、私はPhaseListenerと新しいExceptionHandler APIの助けを借りずに純粋なJSF 2.xアプローチを提案したいと思います。

あなたは本「JSF 2.0:完全なリファレンス」の282ページにViewExpiredExceptionを扱う例見つけることができますオンライン(第一結果のリンクをクリックしてください)here可能です。

+0

こんにちは。アイデアをありがとう。ページ282は利用できません。しかし、いくつかのグーグル・グーグルの後、私はこの種の問題についてedburnの記事を見つけ、この練習を後で使用します:http://weblogs.java.net/blog/edburns/archive/2009/09/03/dealing-gracefully-viewexpiredexception- jsf2 – bertie

3

あなたが作成し、独自の例外ハンドラを登録し、このルートを行くのは本当に簡単ですしている理由はわかりません。 Seam Catch(http://seamframework.org/Seam3/CatchModulehttp://docs.jboss.org/seam/3/catch/3.0.0.Alpha1/reference/en-US/html_single/)が簡単になります。私はまだJSFブリッジを持っていませんが、それは非常に簡単です。そして、あなたがしなければならないのは、特定の例外を処理するメソッドを書くことだけです。

+0

私はまだjsfに新しいとベストプラクティス、したがって上の質問に疑問があります:)提案のおかげで、私はシームフレームワークを使用していませんが、私は例外ハンドラのAPIを見て回ります。 – bertie

関連する問題