本稿では、Spring MVCフレームワークにおけるインターセプターの仕組みについて解説します。インターセプターの定義と設定方法を紹介し、複数インターセプターのチェイン処理の動作を実例で確認した後、ログイン認証の実装を通じて実用的な応用例を示します。
インターセプターの定義
インターセプターは HandlerInterceptor インターフェースを実装することで定義されます。このインターフェースには以下の3つのメソッドが含まれます。
public class CustomInterceptor implements HandlerInterceptor {
// ハンドラメソッド呼び出し前
// 認証・権限チェックに利用
// 認証失敗時は戻り値falseで処理を中断
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// true: 継続、false: 拦截
return true;
}
// ハンドラ実行後、ビュー返却前
// 共通モデルデータ(ナビゲーションなど)を追加可能
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 処理内容
}
// ハンドラ処理完了後
// 例外処理やログ出力に使用
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 処理内容
}
}
preHandle: ハンドラ実行前に呼び出される。リクエストの初期検証(認証、ログイン状態など)に使用。postHandle: ハンドラ実行後に呼び出され、ModelAndViewが生成された直前。共通データの設定やビュー名の統一が可能。afterCompletion: レスポンス送信後に呼び出される。例外処理やリソース解放、ログ記録などが適切。
インターセプターの設定
Spring MVCでは、以下のような構成でグローバルなインターセプターを設定できます。
<!-- グローバルインターセプター設定 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="com.example.interceptor.LoginInterceptor" />
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="com.example.interceptor.LoggingInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
この設定により、すべてのリクエストに対して指定されたインターセプターが適用されます。順序はリストの記述順に従います。
インターセプターの実行順序テスト
複数のインターセプターを設定して、各メソッドの実行タイミングを確認します。
| ケース | preHandle | postHandle | afterCompletion |
|---|---|---|---|
| 両方放行 | Inter1 → Inter2 | Inter2 → Inter1 | Inter2 → Inter1 |
| Inter1放行、Inter2不放行 | Inter1 → Inter2 | なし | Inter1のみ |
| 両方不放行 | Inter1のみ | なし | なし |
ポイント:
preHandleは設定順に実行postHandleとafterCompletionは逆順に実行- いずれかのインターセプターで
falseを返すと、以降の処理は中止
ログイン認証の実装
ユーザーのログイン状態をチェックするインターセプターを実装します。
public class LoginCheckInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String uri = request.getRequestURI();
// 公開パス(ログイン画面など)は許可
if (uri.contains("/login") || uri.contains("/login.action")) {
return true;
}
HttpSession session = request.getSession();
String user = (String) session.getAttribute("username");
if (user != null) {
return true; // ログイン済み
}
// ログイン未済 → ログインページへリダイレクト
request.getRequestDispatcher("/WEB-INF/views/login.jsp").forward(request, response);
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
System.out.println("LoginCheckInterceptor: postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
System.out.println("LoginCheckInterceptor: afterCompletion");
}
}
設定ファイルでの登録:
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="com.example.interceptor.LoginCheckInterceptor" />
</mvc:interceptor>
このように、ログイン状態のチェックを自動的に行うことで、セキュアなアプリケーション設計が可能になります。