springboot2.x基本チュートリアル:フィルターとインターセプターの詳細

Springboot Webプロジェクトの開発中、通常、リクエストのロギング、UAチェック、ユーザー権限の確認、違法なコンテンツのフィルタリングなどの機能など、リクエストとレスポンスのコンテンツのインターセプトをリクエストする必要があります。このとき、フィルターとインターセプターが送信されます。使用する。
この記事では、springbootがフィルターとインターセプターをどのように使用するか、および2つの違いを説明します。

フィルタ

サーブレットフィルタは、要求と応答を動的にインターセプトして、要求または応答に含まれる情報を変換または使用できます。フィルターは、javax.servlet.Filterインターフェースを実装するJavaクラスです。javax.servlet.Filterインターフェースは3つのメソッドを定義します。

public interface Filter {
    default void init(FilterConfig filterConfig) throws ServletException {
    }
    void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
    default void destroy() {
    }
}
シリアルナンバー 方法と説明
1 doFilter
メソッドは実際のフィルタリング操作を完了します。クライアントがフィルター設定と一致するURLを要求すると、サーブレットコンテナーはまずフィルターのdoFilterメソッドを呼び出します。FilterChainユーザーは、後続のフィルターにアクセスします。
2 init
Webアプリケーションが開始されると、WebサーバーはFilterのインスタンスオブジェクトを作成し、そのinitメソッドを呼び出し、web.xml構成を読み取り、オブジェクトの初期化関数を完了し、後続のユーザー要求(フィルターオブジェクト)のインターセプトを準備しますこれは一度だけ作成され、initメソッドは一度だけ実行されます)。開発者は、initメソッドのパラメーターを使用して、現在のフィルター構成情報を表すFilterConfigオブジェクトを取得できます。
destroy
サーブレットコンテナーは、フィルターインスタンスを破棄する前にこのメソッドを呼び出します。この場合、サーブレットフィルターが占有していたリソースが解放されます。

SpringBootはフィルターを使用します

単純なフィルターを定義します

@Slf4j
public class LogFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
         HttpServletRequest req=(HttpServletRequest)servletRequest;
         log.info(req.getRequestURI());
         filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

FilterRegistrationBeanを使用してフィルターを登録する

@Configuration
public class LogFilterConfiguration {
    @Bean
    public FilterRegistrationBean registrationBean(){
        FilterRegistrationBean registrationBean=new FilterRegistrationBean();
        registrationBean.setFilter(new LogFilter());
        //匹配的过滤器
        registrationBean.addUrlPatterns("/*");
        //过滤器名称
        registrationBean.setName("logFilter");
        //过滤器顺序
        registrationBean.setOrder(1);
        return registrationBean;
    }
}

Servlet3.0アノテーションを使用してフィルターを定義する

@WebFilter(urlPatterns = "/*",filterName = "authFiler")
@Slf4j
public class AuthFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
        log.info("进行权限校验.........");
        chain.doFilter(servletRequest,servletResponse);
    }

}

2つの方法の違い:

  1. 注釈WebFilterは実行順序の属性を指定していません。実行順序はフィルターの名前に依存します。フィルターの名前は、フィルタークラス名に従って逆アルファベット順に並べ替えられます(構成されたフィルターの名前ではないことに注意してください)。
  2. @WebFilterによって指定されたフィルターの優先度は、FilterRegistrationBeanによって構成されたフィルターよりも高い
  3. FilterRegistrationBeanメソッドは、BeanをSpringBoot IOCコンテナーに注入できます

インターセプター

SpringBootインターセプターインターセプターと同様のオリエンテッドプログラミングのセクションインフォームで通知機能の拡張機能を追加するための動的プロキシーを使用します。たとえば、初期化プロセスでメソッドが実行される前に、後処理を実行するメソッドの後に実行されますインターセプターのアイデアと同様に、違いはインターセプト要求のみのインターセプターです。service()AOPControllerHTTP

public interface HandlerInterceptor {
    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }

    default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }

    default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    }
}
シリアルナンバー 方法と説明
1 preHandle
メソッドは、コントローラーがリクエストを処理するリクエストを受け取る前に実行されます。戻り値はブール値です。戻り値がtrueの場合、postHandle()メソッドとafterCompletion()メソッドが実行されます。falseが返された場合、実行は中断されます。
2 postHandleは
、コントローラーが要求を処理した後、ModelAndViewが要求を処理する前に実行され、応答結果は変更できます。
afterCompletion
は、DispatchServletがこのリクエストを処理した後、つまりModelAndViewが生成された後に実行されます。

単純なインターセプターを定義する

@Slf4j
public class LogHandler implements HandlerInterceptor {
    private NamedThreadLocal<Long> startTimeThreadLocal = new NamedThreadLocal<>("StopWatch-StartTime");

    public LogHandler() {
        super();
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        long beginTime = System.currentTimeMillis();//1、开始时间      
        startTimeThreadLocal.set(beginTime);//线程绑定变量(该数据只有当前请求的线程可见)
        return true;//继续流程
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        long endTime = System.currentTimeMillis();
        long beginTime = startTimeThreadLocal.get();//得到线程绑定的局部变量(开始时间)  
        long consumeTime = endTime - beginTime;
        //3、消耗的时间         
        log.info(String.format("%s consume %d millis", request.getRequestURI(), consumeTime));
    }    
}

インターセプターの登録

@Configuration
public class HandlerConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LogHandler());
    }
}

フィルターとインターセプターの違い

シリアルナンバー 違い
1 Filterはサーブレット仕様で、使用範囲はWebプログラムです。インターセプターはWebプログラムに限定されず、ApplicationおよびSwingプログラムでも使用できます。
2 フィルターはサーブレット仕様で定義され、サーブレットコンテナーによってサポートされます。インターセプターはSpringコンテナー内にあり、Springフレームワークによってサポートされています
インターセプターはSpringのコンポーネントであり、Serviceオブジェクト、データソース、トランザクション管理、IOCを介したコンテナーへの注入など、Springのオブジェクトを使用できますが、フィルターはできません
4 フィルターはサーブレットの前後で機能し、インターセプターは例外がスローされる前後にメソッドに深く入ります。
5 インターセプターは通常、Springbootプロジェクトで優先されます

千マイルは単一のステップから始まります。これは、SpringBootチュートリアルシリーズの12番目の記事です。すべてのプロジェクトソースコードは、GitHubからダウンロードできます

おすすめ

転載: blog.csdn.net/github_35592621/article/details/108248940