springboot2.x基本チュートリアル:フィルタとブロッキングの詳細

6200 ワード

springboot webプロジェクトの開発過程では、要求ログ記録、UAチェック、ユーザー権限検証、不正コンテンツフィルタリングなどの機能を行うなど、要求と応答のコンテンツ要求ブロック処理が通常必要であり、フィルタとブロックが役に立ちます.ここではspringbootがフィルタとブロッキングをどのように使用するか、そして両者の違いについて説明します.
フィルタ
サーブレットフィルタは、要求および応答を動的にブロックして、要求または応答に含まれる情報を変換または使用することができる.フィルタは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
Initwebアプリケーションが起動すると、webサーバはFilterのインスタンスオブジェクトを作成し、そのinitメソッドを呼び出してwebを読み出す.xml構成では、オブジェクトの初期化機能を完了し、後続のユーザーリクエストをブロックする準備を完了します(filterオブジェクトは1回のみ作成され、initメソッドも1回のみ実行されます).開発者はinitメソッドのパラメータにより,現在のfilter構成情報を表すFilterConfigオブジェクトを得ることができる.
3
destroyServiceletコンテナは、フィルタインスタンスを破棄する前にメソッドを呼び出し、サーブレットフィルタが占有するリソースを解放します.
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;
    }
}

サーブレット3を使用する.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つの方法の違い:
  • WebFilterという注釈は、実行順序の属性を指定するものではなく、その実行順序はFilterの名前に依存し、Filterクラス名(構成されたfilterの名前ではないことに注意)によるアルファベット順逆配列
  • である.
  • @WebFilterで指定したフィルタ優先度は、いずれもFilterRegistrationBean構成のフィルタ
  • よりも高い
  • FilterRegistrationBean方式SpringBoot IOC容器に注入可能なBean
  • ブロッキング
    SpringBootブロッカーInterceptorは、スライスプログラミングにおけるスライスと通知と同様に、動的エージェントによってservice()メソッドに通知を追加する機能を強化します.例えば、メソッド実行前に初期化処理を行い、メソッド実行後に後置処理を行う.ブロッキングの考え方はAOPと類似しており、違いは、ブロッキングがControllerHTTP要求に対してのみブロックできることである.
    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この方法は、controllerがリクエスト処理requestを受信する前に実行され、戻り値がbooleanであり、戻り値がtrueである場合にpostHandle()およびafterCompletion()メソッドが実行される.falseを返すと実行が中断されます.
    2
    postHandleはcontroller処理要求の後,ModelAndView処理の前に実行され,応答結果を修正することができる.
    3
    afterCompletionは、DispatchServiceletによる今回の要求処理が完了した後、ModelAndViewが生成された後に実行される.
    簡単なブロッキングを定義
    @Slf4j
    public class LogHandler implements HandlerInterceptor {
        private NamedThreadLocal 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はservlet仕様、使用範囲はwebプログラム、ブロッカーはwebプログラムに限らずApplication、Swingプログラムにも使用可能
    2
    Filterはservlet仕様で定義され、servletコンテナでサポートされています.インターセプタはSpringコンテナ内、springフレームでサポートされています
    3
    インターセプタはSpringのコンポーネントで、Springのオブジェクト、例えばServiceオブジェクト、データソース、トランザクション管理、IOCを通じてコンテナを注入すればよいが、filterは
    4
    filterはservlet前後に作用し,ブロッキングは方法の前後に深く入り込み,異常に前後を投げ出すことができる.
    5
    スプリングbootプロジェクトでは一般的にブロックを優先的に使用します
    千里の道も一歩から始まる.ここはSpringBootチュートリアルシリーズの第12編で、すべてのプロジェクトのソースコードは私のGitHubの上でソースコードをダウンロードすることができます.