概要
HandlerInterceptorの基本的な使用方法についてまとめた。
HandlerInterceptor
HandlerInterceptorは、コントローラのハンドラメソッド実行前後に共通処理を挟むための仕組みとなる。
ログ記録、認証、セッション検証などに利用される。
サーブレットフィルタとの違い
HandlerInterceptorとサーブレットフィルタは以下のような違いがある。
特性 | HandlerInterceptor | サーブレットフィルタ |
---|---|---|
適用範囲 | Controllerのハンドラメソッドの前後 | 全てのServletリクエストの前後 |
実行タイミング | DispatcherServlet以降 | DispatcherServlet以前 |
主な用途 | 認証、ロギング、セッション検証など | 認証、ロギング、文字コード設定、アクセス制御など |
定義方法 | WebアプリケーションコンテキストにBean定義 | web.xmlの設定、またはルートアプリケーションコンテキストにBean定義 |
基本的な使い方
HandlerInterceptorは、基本的にorg.springframework.web.servlet.HandlerInterceptorインターフェースを実装して
以下のメソッドを適宜オーバーライドして使用する。
メソッド | 説明 |
---|---|
preHandle(…) | Controller実行前に呼ばれる リクエスト前処理を行う 戻り値にfalseを返すと処理を中断しControllerのハンドラメソッドは呼ばれない |
postHandle(…) | Controller実行後(View描画前) 、処理が正常に完了した後に呼ばれる(※例外が発生すると実行されない) ModelやViewの加工が可能 |
afterCompletion(…) | リクエスト完了後 Viewの描画が終わった後に呼ばれる(※例外が発生していても必ず実行される) リソース解放やログ出力などに利用 |
実装方法
基本的なHandlerInterceptorを実装する方法を紹介する。
HandlerInterceptorの実装
HandlerInterceptorの実装クラスを用意する。
HandlerLoggingInterceptor.java
package com.example.prototype.web.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class HandlerLoggingInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(HandlerLoggingInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// コントローラーのハンドラメソッド実行前
logger.info("★★リクエスト開始★★");
// 以下でfalseを返却するとハンドラメソッドは呼ばれない
// 代わりに任意のレスポンス(JSONなど)を返却できる
return HandlerInterceptor.super.preHandle(request, response, handler);
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// コントローラーのハンドラメソッド実行後(例外なし)
logger.info("★★コントローラー処理完了★★");
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// レスポンス完了後(例外があっても呼ばれる)
logger.info("★★レスポンス完了★★");
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
ハンドラ実行前に共通処理を行いたい場合、このメソッドをオーバーライドして定義する。
戻り値にfalseを設定すると、ハンドラメソッドはスキップされる。
ハンドラの処理が完了後に共通処理を行いたい場合、このメソッドをオーバーライドして定義する。
ハンドラ内にて例外がスローされると実行されない。
Viewの描画まで完了した後に共通処理を行いたい場合、このメソッドをオーバーライドして定義する。
DIコンテナに登録
WebアプリケーションコンテキストにBean定義して、作成した共通処理を有効にする。
springMVCContext.xml
<!-- HandlerInterceptorを適用させるためのBean定義 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" /><!-- 適用対象のパス -->
<mvc:exclude-mapping path="/resources/**"/><!-- 除外対象のパス -->
<bean class="com.example.prototype.web.interceptor.HandlerLoggingInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
Spring MVCで使用するInterceptorの一覧を定義するタグ。
複数のInterceptorを登録できる。
個別のInterceptorを定義するタグ。
Interceptorを適用させるリクエストパスを定義する。
Interceptorを適用させないリクエストパスを定義する。
作成したInterceptorのBeanを定義する。
まとめ
☑ HandlerLoggingInterceptorはコントローラーのハンドラメソッドに共通処理を定義するために使用する
☑ WebアプリケーションコンテキストにBean定義して使用する
☑ 認証、ロギング、セッション検証などの用途で使用する