1. 概要

この記事では、JavaサーブレットFilterとSpringMVC HandlerInterceptor、を比較し、一方が他方よりも好ましい場合を比較します。

2. フィルターs

フィルターはWebサーバーの一部であり、Springフレームワークではありません。着信リクエストの場合、フィルターを使用して、リクエストがサーブレットに到達するのを操作したり、ブロックしたりすることができます。 逆に、応答がクライアントに到達するのをブロックすることもできます。

Spring Security は、認証と承認にフィルターを使用する優れた例です。 Spring Securityを構成するには、DelegatingFilterProxyという単一のフィルターを追加するだけです。 その後、SpringSecurityはすべての着信および発信トラフィックを傍受できます。 これが、SpringSecurityをSpringMVCの外部で使用できる理由です。

2.1. フィルターの作成

フィルタを作成するには、まず、javax.servlet.Filterインターフェイスを実装するクラスを作成します。

@Component
public class LogFilter implements Filter {

    private Logger logger = LoggerFactory.getLogger(LogFilter.class);

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
      throws IOException, ServletException {
        logger.info("Hello from: " + request.getLocalAddr());
        chain.doFilter(request, response);
    }

}

次に、 doFilter メソッドをオーバーライドします。このメソッドでは、 ServletRequest ServletResponse 、またはFilterChainオブジェクトにアクセスまたは操作できます。 FilterChain オブジェクトを使用して、リクエストを許可またはブロックできます。

最後に、 フィルターで注釈を付けることにより、Springコンテキストに @成分。 残りは春がやってくれます。

3. HandlerInterceptor s

HandlerInterceptorsはSpringMVCフレームワークの一部であり、DispatcherServletとコントローラーの間に位置します。 リクエストがコントローラーに到達する前、およびビューがレンダリングされる前後に、リクエストをインターセプトできます。

3.1. HandlerInterceptorの作成

HandlerInterceptor を作成するには、org.springframework.web.servlet.HandlerInterceptorインターフェースを実装するクラスを作成します。 これにより、次の3つのメソッドをオーバーライドするオプションが提供されます。

  • preHandle() –ターゲットハンドラーが呼び出される前に実行されます
  • postHandle() –ターゲットハンドラーの後、DispatcherServletがビューをレンダリングする前に実行されます
  • 完了後() – リクエスト処理とビューレンダリングの完了後のコールバック

テストインターセプターの3つのメソッドにログを追加しましょう。

public class LogInterceptor implements HandlerInterceptor {

    private Logger logger = LoggerFactory.getLogger(LogInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 
      throws Exception {
        logger.info("preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) 
      throws Exception {
        logger.info("postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) 
      throws Exception {
        logger.info("afterCompletion");
    }

}

4. 主な違いとユースケース

FilterHandlerInterceptorが要求/応答フローのどこに適合するかを示す図を見てみましょう。

フィルターは、DispatcherServletに到達する前に要求をインターセプトするため、次のような粗粒度のタスクに最適です。

  • 認証
  • ロギングと監査
  • 画像とデータの圧縮
  • SpringMVCから切り離したい機能

一方、 HandlerInterceporsは、DispatcherServletとコントローラー間のリクエストをインターセプトします。これはSpring MVCフレームワーク内で行われ、HandlerおよびModelAndViewへのアクセスを提供します。オブジェクト。 これにより、重複が減り、次のようなよりきめ細かい機能が可能になります。

  • アプリケーションロギングなどの横断的関心事の処理
  • 詳細な承認チェック
  • Springコンテキストまたはモデルの操作

5. 結論

この記事では、FilterHandlerInterceptorの違いについて説明しました。

重要なポイントは、フィルターを使用すると、リクエストがコントローラーに到達する前に、Spring MVCの外部でリクエストを操作できることです。それ以外の場合、 HandlerInterceptor は、アプリケーション固有の横断的関心事に最適な場所です。懸念。 ターゲットのHandlerおよびModelAndViewオブジェクトへのアクセスを提供することにより、よりきめ細かい制御が可能になります。

これらすべての例とコードスニペットの実装は、GitHubにあります。