Spring Boot インターセプターの実装: ログイン検証、統合例外処理、戻りデータの正規化



        Springやサーブレットを学び始めた当初は、ユーザーの身元を判定する際にセッションやオブジェクトをそれぞれのメソッドで取得していましたが、この方法では冗長性が高く、コードが複雑になり、保守コストも高くなるため、AOPの利用を考えました。パブリック メソッドを実装します。このパブリック メソッドは、ユーザーの ID を決定するために特に使用されます。ただし、AOP 通知メソッドは断面全体によってインターセプトされます。したがって、ユーザーの ID を決定する必要がない一部のメソッドの場合、このアプローチは次のようになります。また、AOP を使用してパラメータを取得することも困難であるため、Spring Boot インターセプタを使用する方が適切です。

        以下のインターセプタは、(1) 統合ログイン検証、(2) 統合例外処理、(3) 統合戻りデータ形式という 3 つの実用的な機能を実装するために使用されます。


1. 統合ログイン認証:

ステップ 1: インターセプターをカスタマイズする

        共通クラスを作成し、HandlerInterceptor インターフェイスを実装し、preHandle メソッドをオーバーライドしますインターセプターは非常に一般的に使用されるため、Spring Boot にはインターセプターへの依存関係が組み込まれています。

  1. preHandleメソッド:リクエストがコントローラーに到達する前に呼び出されます。インターセプター チェーン内の各インターセプターのpreHandleが順番に呼び出されます。インターセプターpreHandleメソッドが を返したfalse、後続のインターセプターpreHandleメソッドとコントローラー メソッドは実行されず、リクエストはインターセプトされます。

  2. postHandleメソッド: Controller メソッドが実行された後、DispatcherServlet がビューをレンダリングする前に呼び出されます。インターセプター チェーン内の各インターセプターのpostHandleが順番に呼び出されます。このメソッドでは、ModelAndView を処理したり、パブリック モデル データを追加したりできます。

  3. afterCompletionメソッド: DispatcherServlet がビューのレンダリングを完了した後に呼び出されます。インターセプター チェーン内の各インターセプターのafterCompletionが順番に呼び出されます。このメソッドでは、リソースの解放、ログの記録など、一部のリソースのクリーンアップ操作を実行できます。このメソッドは、リクエスト処理プロセス全体が完了した後に呼び出されます。

ステップ 2: インターセプト構成を登録する

        WebMvcConfigurer インターフェイスを実装し、addInterceptor メソッドをオーバーライドするための共通メソッドを作成します。目的は、システム構成項目にカスタム インターセプターを構成し、適切なインターセプト パスを設定することです。

ステップ 3: コントローラー メソッドを追加する 

 実行効果: ログインは入力できませんが、登録は入力できます


拡張子: 統合アクセス プレフィックスを追加します。

        シナリオを想定すると、複数のプロジェクトに同じ名前の URL がある場合、パケット キャプチャのテストなどの観察プロセス中に、それらがどのプロジェクトに属しているかをどのように区別すればよいでしょうか?

        リクエストアドレスにアクセスプレフィックスを付加することで区別できます。

 プレフィックスを追加した後、インターセプト パスを忘れずに変更してください。


2. 統合された例外処理:

        統一された例外処理とは、一部のメソッドが同じ種類の例外をトリガーする可能性があることを意味し、インターセプターを使用して例外を均一にインターセプトして取得し、合意に従って必要な結果を返すことができます。

ステップ 1: 例外処理クラスとメソッドを作成する

        すべての例外クラスをキャッチするためのメソッドを含む共通クラスを作成します。@ControllerAdvice アノテーションを処理クラスに追加し、@ExceptionHandler アノテーションをカスタム インターセプト メソッドに追加します。キャッチされる例外クラス オブジェクトをアノテーション内のパラメータとして渡します。

 ステップ 2: 例外を引き起こす可能性のあるメソッドを作成する

例外検出があり、対応する例外が発生した場合でも、サーバーは例外処理メソッドの規定に従って、フロントエンドに返されるべきものを返します。

 例外が検出されない場合、対応する例外が発生したとしても、サーバーの戻りは合意とは何の関係もありません。

2.1 父子の異常:

        上記の場合、@ExceptionHandler アノテーション パラメーターに例外が 1 つだけある場合、この例外のみをキャプチャして処理できます。多数の例外を処理する場合は、それぞれの例外に対してメソッドを記述する必要はありません。パラメータ内のすべての例外の親クラスを直接渡します。例外クラスは次のとおりです: Exception.class

        子例外処理メソッドと親例外処理メソッドが同時に存在する場合、子の例外検出メソッドが最初に照合されます。


3. 統一されたデータ形式は以下を返します。

        日々の開発では、各バックエンド業務からフロントエンドに返すデータ形式は、あらかじめ決められた形式に準拠している必要がありますが、取り決めた形式を忘れてしまったり、初めての人があらかじめ決められた形式を知らない場合、データを返してしまう可能性があります。自らの思いつきで業務上の事故を引き起こす可能性があります。

        @ControllerAdvice アノテーション + ResponseBodyAdvice インターフェースを使用して統一されたデータ返却を実装し、規約に準拠した返却データ形式をカスタムクラスに設定し、各事業者から返却されるデータをインターセプトして、返却されるデータ形式が準拠しているかどうかを判定することができます。一致しない場合は、データを再カプセル化し、インターセプト ルールでデータ形式を返します。

        統一データ返却の義務付け、データ返却前のデータ書き換え

ステップ 1: データ処理クラスを作成する

        共通クラスを作成し、ResponseAdvice インターフェイスを実装し、supports() メソッドと beforeBodyWrite() メソッドをオーバーライドします。

  • Supports() メソッド:このメソッドはスイッチに相当し、インターセプトしたコンテンツを書き換えるかどうかを処理メソッドに指示するために使用され、書き換える必要があることを示すために true を返します。
  • beforeBodyWrite() メソッド:ビジネス メソッドによって返されるデータをインターセプトし、独自のデータを返す前に間違った形式でデータを書き換えます。

 ステップ 2: 間違った形式のデータを生成する可能性のある 2 つのメソッドを作成する

         getRet1() メソッドは 1 を返し、getRet2() メソッドは hashMap を返します。
        正しい形式は hashMap です。

 要約:

このカスタム インターセプト データ形式の戻りには 2 つの問題があります。

1. 処理メソッドに設定される戻り内容の値はハードコーディングされています。

2. String 型が返された場合、正しいデータに処理できません。

3.1 拡張: String 型の戻り値の変換エラーの問題を解決

        getRer3() メソッドは文字列を返します。これをインターセプトしてカプセル化された hashMap に変換して返すのが理想的な状態ですが、変換できないため実行されず、クラス変換例外が発生し、例外処理クラスが戻り例外をキャッチしました: HashMap を String に変換できません

間違った理由:

        明らかに String を hashMap に変換しているのに、エラー メッセージが逆になるのはなぜですか?

ここで、リターン実行プロセスを理解する必要があります。

  1. 元のメソッドによって返される元の本体は String 型です。
  2. 統合データを返す前に: 文字列を hashMap に変換します。
  3. ブラウザは StringHttpMessageConverter を使用して hashMap を json 文字列に変換します。

問題は 3 番目のステップにあります。ブラウザは元の本文を使用して String 型かどうかを判断します。そうである場合は、StringHttpMessageConverter を使用して hashMap を json に変換します。変換できないことが判明したため、エラーが報告されます。

解決策 1:

統合データを書き換える際、戻り値が String 型の場合は個別に処理され、HashMap の代わりに Json 文字列 (結合およびジャクソンが使用可能) を返すように書き換えられます。

 Jackson を使用して文字列に変換します。

解決策 2:

        問題はブラウザのコンバータにあるため、このコンバータを使用しない方法を見つけます。

        StringHttpMessageConverter コンバーターは手動で削除できます。

 これで大丈夫です:


4. インターセプターの実装原則:

 図:

        すべてのコントローラーの実行は、スケジューラー DispatcherServlet を通じて実装されます。

上の図は、インターセプターの実装原理を説明しています。

  1. リクエストは、リクエストの受信と配布を担当するフロントエンド コントローラーである DispatcherServlet に到着します。

  2. DispatcherServlet は、設定されたインターセプター チェーンに従って、各インターセプターのメソッドを順番に呼び出します。

  3. インターセプター チェーン内の各インターセプターは HandlerInterceptor インターフェイスを実装し、インターセプターのメソッドはリクエスト処理のさまざまな段階で呼び出されます。

  4. 各インターセプター メソッドの呼び出しの前後で、戻り値を使用して、次のインターセプター メソッドまたはコントローラー メソッドの実行を継続するかどうかが決定されます。

  5. すべてのインターセプター メソッドが実行されると、DispatcherServlet はビューをレンダリングし、応答結果を生成します。

インターセプターの実装を通じて、リクエスト処理をさまざまな段階でインターセプトして処理し、アクセス許可の検証、ロギング、例外処理などのいくつかの一般的な機能を実装できます。インターセプターの実装原理は Java のリフレクション メカニズムと設計パターンに基づいており、動的プロキシを通じてプロキシ オブジェクトが生成され、インターセプターの呼び出しを実装します。

おすすめ

転載: blog.csdn.net/m0_65190367/article/details/131942087