1. test 1
  2. test 2
  3. test 3
  4. test 4
  5. test 5
  6. test 6
  7. test 7
コース一覧
Spring Boot入門
フィルタとインターセプタ

Spring Boot入門

Java で Web API サーバーを作るための Spring Boot の入門コースです。DI コンテナ、REST コントローラ、リクエスト検証、レイヤ分割、Spring Data JPA、例外ハンドリング、テストまでを扱います。毎レッスン、Spring が裏側でやっている判断そのものを pure Java の関数として自分で書き、フレームワークが何を肩代わりしてくれているのかを手触りで理解できる構成にしました。約 12 時間 (1 日 30 分 × 24 日) で 48 レッスンを修了できます。

1
Spring Bootとは何か
01. Spring Bootで何が作れるのか10分
02. サーブレットからフレームワークへ15分
03. ルーティング表という発想15分
04. プロジェクトの構成10分
05. 起動のしくみと自動設定15分
06. パスのマッチング15分
2
DIコンテナ
01. newで書くと何が困るのか15分
02. コンストラクタインジェクション15分
03. インターフェースへの依存15分
04. @Componentと@Bean15分
05. 自作のDIコンテナ20分
06. Beanのスコープとライフサイクル15分
3
RESTコントローラ
01. RESTという設計方針15分
02. @RestControllerの役割15分
03. @GetMappingとパス変数15分
04. クエリパラメータの受け取り15分
05. @PostMappingとリクエストボディ15分
06. ステータスコードの選び方15分
07. ResponseEntityで組み立てる15分
4
リクエストとレスポンスの変換
01. JSONとオブジェクトの往復15分
02. DTOとエンティティを分ける15分
03. recordでDTOを書く15分
04. 入力検証の基本15分
05. 検証エラーをまとめて返す15分
06. アノテーションによる検証15分
5
レイヤ構成とビジネスロジック
01. 3層アーキテクチャ10分
02. @Serviceに置くもの15分
03. 状態遷移をルールにする15分
04. 料金計算のような業務ロジック15分
05. @Transactionalとは何か15分
06. トランザクションの巻き戻し15分
6
データアクセス
01. @Entityとテーブルの対応15分
02. リポジトリという抽象15分
03. メソッド名からクエリを作る20分
04. 検索条件の組み立て15分
05. ページングと並び替え15分
06. N+1問題15分
7
例外処理と横断的関心事
01. 例外をHTTPに変換する15分
02. @ExceptionHandlerと@ControllerAdvice15分
03. エラーレスポンスの形を決める15分
04. フィルタとインターセプタ15分
05. ログとリクエストの追跡15分
06. 設定値の外部化15分
8
テストと仕上げ
01. テストの種類と使い分け15分
02. Serviceの単体テスト15分
03. モックで依存を差し替える15分
04. MockMvcでエンドポイントを試す15分
05. 本番へ出すための次の一歩10分

フィルタとインターセプタ

このレッスンでは、すべてのリクエストが必ず通る共通の通り道である Filter と HandlerInterceptor の違いを理解し、チェーンという考え方を身につけます。

全リクエストに共通する処理をどこに置くか

認証、ログ出力、文字コードの設定、処理時間の計測。こうした処理は、特定のコントローラだけでなくすべてのリクエストに必要です。かといって全ハンドラメソッドの先頭に同じ 3 行を書き写すのは現実的ではありません。リクエストが通る道の途中に、共通処理を差し込む場所が用意されています。

Spring MVC のリクエストは、大きく言うと次の順で流れます。

プレーンテキスト

クライアント -> サーブレットコンテナ (Tomcat) -> Filter チェーン -> DispatcherServlet -> HandlerInterceptor -> Controller のハンドラメソッド <- HandlerInterceptor <- DispatcherServlet <- Filter チェーン <- クライアント

Filter は外側、Interceptor は内側

この図が示すとおり、Filter と HandlerInterceptor の最大の違いは立ち位置です。

FilterHandlerInterceptor
仕様の出どころサーブレット仕様 (jakarta.servlet)Spring MVC 独自
位置DispatcherServlet の外側DispatcherServlet の内側
対象そのアプリへ来るすべてのリクエストDispatcherServlet が扱うリクエスト
どのハンドラが呼ばれるかを知れるか知れない知れる
向く用途文字コード、認証、リクエスト本文の書き換えハンドラごとの権限確認、処理時間の計測

Filter はサーブレットの世界の道具なので、Spring がまだ何も判断していない段階で動きます。リクエストやレスポンスをラップして中身を差し替えられるのが強みです。一方 HandlerInterceptor は Spring MVC の中で動くので、preHandle の引数として「これからどのハンドラが呼ばれるのか」を受け取れます。ハンドラに付いた独自アノテーションを見て通す通さないを決める、といった芸当は Interceptor でなければできません。

Java

public class LoggingFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { long start = System.currentTimeMillis(); chain.doFilter(req, res); // 次へ渡す。これを呼ばないとここで止まる long elapsed = System.currentTimeMillis() - start; } }

チェーンは順に通り、途中で切れます

Filter は 1 つとは限らず、複数が数珠つなぎになります。ここで覚えるべき性質が 2 つあります。1 つは、登録した順に前から適用されるということ。もう 1 つは、chain.doFilter を呼ばずに応答を書いてしまえば、その先のフィルタもコントローラも一切呼ばれない、ということです。認証フィルタが未認証のリクエストを 401 で打ち切るのは、まさにこの性質を使っています。

順序が意味を持つ場面は多くあります。認証フィルタの前にログフィルタを置けば未認証のリクエストも記録できますが、後ろに置けば認証を通ったものしか記録されません。どちらが正しいかは目的次第で、だからこそ順序は意識して決める必要があります。Spring Boot では FilterRegistrationBean の setOrder や @Order で順序を指定できます。

演習で書くもの

Spring が FilterChain の中で行っている「前から順に適用し、拒否が出たらそこで打ち切る」という制御そのものを、自分で書きます。フィルタの並びを名前の列として受け取り、順に適用した結果を返してください。途中のフィルタが拒否したら、そこで打ち切って理由を返します。実際の Filter が chain.doFilter を呼ばずに応答を返す状況にあたります。

要件

  1. フィルタは前から順に適用し、後ろのフィルタは前のフィルタの結果を受け取ること
  2. auth と length が拒否したら、その場で打ち切って rejected by という接頭辞の付いた理由を返すこと
  3. 未知のフィルタ名は rejected by unknown を返し、名前の並びが空なら本文をそのまま返すこと

入出力例

runChain("trim,upper", " hello ") → "HELLO" runChain("auth,upper", "token abc") → "ABC" runChain("auth,upper", "abc") → "rejected by auth" runChain("trim,length,upper", " this text is definitely long ") → "rejected by length" runChain("upper,cache", "hi") → "rejected by unknown" runChain("", "hi") → "hi" runChain("auth,trim,length,upper", "token ok ") → "OK"

ヒント

split でカンマ区切りを配列にし、拡張 for 文で回します。名前は trim してから比べます

現在の本文を変数に持ち、フィルタごとに上書きしていくと順に適用する形になります

拒否は途中で return してしまえば、それ以降のフィルタは実行されません

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/08/09

関連レッスン

  • ログとリクエストの追跡

    リクエストを識別する ID を組み立て、追跡できるようにします。

  • 設定値の外部化

    設定ファイルの key=value を解析し、既定値を適用します。

  • テストの種類と使い分け

    @SpringBootTest と @WebMvcTest の違いを確認します。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • リクエストWeb 通信の基本単位、ブラウザの問い合わせとサーバーの返答
  • 処理計算や代入を表す長方形
  • 認証「この人は本当に本人?」のチェック
  • 文字コード文字に番号を割り当てるルール体系
  • メソッドクラスに属する関数
  • 判断YES/NO 分岐を表す菱形
  • 引数位置引数=順番で渡す。
main.java
学習モード
エディタを読み込んでいます

メモ

フィルタとインターセプタ

⌘S で保存