SpringMVCにおけるインターセプターの活用と統合例外処理の仕組み

SpringMVCインターセプターの役割

インターセプターは、ServletAPIのフィルター(Filter)に類似した機能を提供し、コントローラーへの要求前後の処理(プリプロセス、ポストプロセス)を実装するためのコンポーネントです。複数のインターセプターを連結することでインターセプターチェーンを構成し、設定された順序に従って処理が実行されます。これはAOP(Aspect Oriented Programming)の思想をWebリクエスト処理に適用した具体的な実装例と言えます。

フィルターとインターセプターの相違点

比較項目 フィルター (Filter) インターセプター (Interceptor)
適用範囲 Servlet仕様の一部であり、Java Webアプリケーション全般で利用可能。 SpringMVCフレームワークに依存しており、SpringMVCを導入したプロジェクトでのみ使用可能。
制御範囲 URLパターンに基づき、全てのリソース(静的ファイル含む)へのアクセスを遮断可能。 パス設定によりリソースを制御可能。 finer-grainedな制御ができ、特定のパスを除外する設定も容易。

インターセプターの実装手順

  1. HandlerInterceptorインターフェースを実装したクラスを作成する。
  2. Spring設定ファイルにてインターセプターを登録する。
  3. 動作を検証する。
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class AccessLogInterceptor implements HandlerInterceptor {

    // コントローラーのメソッドが実行される前に呼び出される
    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) throws Exception {
        System.out.println("[PreHandle] リクエスト受信: " + req.getRequestURI());
        return true; // falseを返すと、ここで処理が中断されコントローラーへ到達しない
    }

    // コントローラー処理完了後、ビュー描画前に呼び出される
    @Override
    public void postHandle(HttpServletRequest req, HttpServletResponse res, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("[PostHandle] モデル生成完了: " + (modelAndView != null ? modelAndView.getViewName() : "null"));
    }

    // 全ての処理(ビュー描画含む)完了後に呼び出される
    @Override
    public void afterCompletion(HttpServletRequest req, HttpServletResponse res, Object handler, Exception ex) throws Exception {
        System.out.println("[AfterCompletion] リクエスト処理完了");
    }
}
<!-- Spring設定ファイル内 -->
<mvc:interceptors>
    <!-- 特定のインターセプターの定義 -->
    <mvc:interceptor>
        <!-- 全てのパスを対象とする -->
        <mvc:mapping path="/**"/>
        <!-- インターセプタークラスの指定 -->
        <bean class="com.example.web.interceptor.AccessLogInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

例外処理メカニズム

システム内部で発生する例外は、主に「予期される例外(Checked Exception)」と「実行時例外(RuntimeException)」に大別されます。前者はキャッチして情報をハンドリングし、後者はコードの品質向上やテストによって発生を抑える必要があります。アーキテクチャ上は、Dao層、Service層、Controller層で発生した例外を throws Exception により上位へ伝播させ、最終的にSpringMVCのフロントコントローラー(DispatcherServlet)が例外ハンドラー(Exception Resolver)へ処理を委譲します。

例外処理のアプローチ

SpringMVCにおける例外処理には、大きく分けて2つの手法があります。

  • Springが提供するSimpleMappingExceptionResolverを使用する(宣言的アプローチ)。
  • HandlerExceptionResolverインターフェースを実装し、独自のハンドラーを作成する(プログラマティックアプローチ)。

SimpleMappingExceptionResolverの設定例

このリゾルバーは、例外のクラス型と遷移先のビュー(JSPなど)をマッピングするだけで容易にエラーページへの遷移を実現できます。

<bean id="simpleExceptionResolver" 
      class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    
    <!-- デフォルトのエラービュー -->
    <property name="defaultErrorView" value="systemError"/>
    
    <!-- 例外クラスとビューのマッピング -->
    <property name="exceptionMappings">
        <props>
            <prop key="java.lang.NullPointerException">pageNotFound</prop>
            <prop key="java.lang.ArithmeticException">calculationError</prop>
        </props>
    </property>
</bean>

カスタム例外ハンドラーの実装手順

  1. HandlerExceptionResolverインターフェースを実装したクラスを作成し、resolveExceptionメソッド内で処理ロジックを記述する。
  2. 作成したクラスをSpringのBeanとして登録する。
  3. 遷移先となるエラーページ(JSP/HTML)を作成する。
  4. 意図的に例外を発生させ、適切にハンドリングされるかテストを行う。

7月29日 07:40 投稿