システム開発で思うところ

Javaで主にシステム開発をしながら思うところをツラツラを綴る。主に自分向けのメモ。EE関連の情報が少なく自分自身がそういう情報があったら良いなぁということで他の人の参考になれば幸い

プレゼンテーション層で例外を扱う(私の例)

への私なりの回答です。

Javaの王道ではないと思いますし、過去のオレオレライブラリでは、こういう風にしたよってだけの話です。*1

正直、現時点では「うーん、発想は悪くなさそうだけど、見直ししたいな」と思っています。

とりあえず

「HTML返す場合で一律のエラーページに飛ばさずに画面の表示をエラー文言にしたい、とかの場合はtry-catchするしかないのか?」

への、私なりの回答です。

ちなみに、元々はトランザクションの話だったと思いますが、最終的なところはプレゼンテーション層との連携、ということとして回答します。

細かい前提は抜きにして、Interceptor(イメージ)を示します。

実際のコードは、もっと変なことを色々しているので、過去のコードを横目に それっぽい感じにしたものです。

私はJSFを使っているので、SpringMVCなどフレームワークだと の処理画面の情報の取得のやり方について、参考にならないかもしれませんが。。

public class ActionInterceptor {

    @Inject
    MessageItem messageItem;

    @AroundInvoke
    public Object invoke(InvocationContext ic) throws Exception {

        // 処理実行開始時点の画面IDを取得する。
        Object result = FacesContext.getCurrentInstance().getViewRoot().getViewId();

        try {
            result = ic.proceed();
            return result;
        } catch (CustomException ex) {
            /*
            実行時例外に独自の情報(メッセージIDとか、その他の付加情報)を持たせておいて、
            それを元に画面のメッセージを設定する
             */
            this.messageItem.setMessage(ex);

            /*
            例外があった場合は、実行時の画面IDを返却する。
            (もし、CustomException で保持している内容次第で、遷移先を変えたかったらここで何か実装する。)
             */
            return result;
        }
    }
}

なお、ExceptionHandler でシステム全体で共通してやっても良いように思います。

この実装を やったときは Interceptorで実装する方式しか イメージできなかったけれど、今なら、、どうかなぁ ちょっと分かりません。

ExceptionHandlerにするかもしれないです。

遷移前の情報など、その他の参照したい情報や適用されるタイミング次第だと思います。

ちなみに、当初は Controller で try-catch してメッセージ用のインスタンスに値を設定するUtilをCallする方式にしていました。

そのときは「レイヤー間を跨る例外は、検査例外にして 明示化するべきではないか?」と思っていたからです。

ですが、実際にやってみて 独自例外はメッセージIDが違うだけで型は1つ、いちいち try-catch を書くのが面倒くさくなって、上述の実行時例外での方式に編集しました。

おかげ様で、Controllerのメソッドに例外ハンドリングの記述が無くなった分だけ、スッキリしました。

*1:逃げ腰