埋め込まれたコンテナを使用して春ブーツ、どのようにカスタムフィルタを設定するには、それ

ListenerFilterそしてServletJavaのWeb開発プロセスは、一般的に3つのコンポーネントが、使用されることが多い簡単な処理権限、リクエストヘッダを作成し、防止するためにフィルタリングするために使用される最高周波数成分フィルタ、XSS攻撃。私たちは、伝統的なSpring MVCの開発を使用している場合は、唯一の次のような構成は、Tomcatのweb.xml内のファイルに必要とされています。

<!-- 配置Listener -->
<listener>
    <listener-class>org.springframework.web.util.WebAppRootListener</listener-class>
</listener>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> 

<!--配置Filter,这边配置了一个Filter,但是匹配了多个url-pattern-->
<!-- 以url-partern方式配置的filter中,如果有多个与当前请求匹配,则按web.xml中filter-mapping出现的顺序来运行-->
<filter>  
    <filter-name>filter1</filter-name>  
    <filter-class>com.csx.MyFilter</filter-class>  
</filter>  
<filter-mapping>
    <filter-name>filter1</filter-name>  
    <url-pattern>/url/a/*</url-pattern>  
</filter-mapping>  
<filter-mapping>  
    <filter-name>filter1</filter-name>  
    <url-pattern>/url/b/*</url-pattern>  
</filter-mapping>

<!--配置Servlet-->
<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc.spring.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <!-- 这边不建议写成/* -->
    <url-pattern>/</url-pattern>
</servlet-mapping>

PS:コンテナが開始されると、3以上のコンポーネントの起動シーケンスは、リスナーである - >フィルタ - >サーブレット、サイドアムウェイメモリの方法:メモリブートシーケンスに「李(リスナー)が発行(フィルター)部門(サーブレットは)「することができます。

web.xmlで構成され、これら3つのコンポーネントが比較的簡単ですが、春ブーツの開発を使用してコンテナに埋め込まれ、かつのconfigure web.xmlファイルに私たちを許可していませんでした。だから、最終的にどのように春ブートを設定しListenerFilterそしてServlet、それの他のコンポーネント?

このブログFilterの列は、春・ブートの設定方法を紹介ListenerFilterおよびServletその他のコンポーネント。

一つの方法:フィルター宣言豆

ここで、我々は最初のフィルターを定義することから、この効果は統計的なインターフェースを呼び出すための時間であるフィルタ。

public class TimeConsumingCalculationFilter implements Filter {

        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            HttpServletRequest httpRequest=(HttpServletRequest)request;
            long startTime = System.nanoTime();
            logger.info(">>>>>>> Begin ["+httpRequest.getRequestURI()+"]...");
            try{
                chain.doFilter(request, response);
            }finally {
                long endTime = System.nanoTime();
                logger.info(">>>>>>> End ["+httpRequest.getRequestURI()+"]["+(endTime-startTime)/1000/1000.0+"ms].");
            }
        }

    }

春ブーツの上にあるフィルタの設定、我々は必要な@Configurationファイルに次の設定を行うには:

@Configuration
public class WebConfig {

    private static Logger logger = LoggerFactory.getLogger(WebConfig.class);

    @Bean
    public Filter filter1(){
        return new TimeConsumingCalculationFilter();
    }
}

フィルタのデフォルトは、上記のすべての要求をインターセプトします。我々は複数のインターセプタを設定したい場合は、ちょうどそれにBeanメソッドを追加します。

@Configuration
public class WebConfig {

    private static Logger logger = LoggerFactory.getLogger(WebConfig.class);

    @Bean
    public Filter filter1(){
        return new TimeConsumingCalculationFilter();
    }
    
    @Bean
    public Filter filter2() {
        return new TimeConsumingCalculationFilter2();
    }
}

>フィルタ2 -フィルタ1:2つのコンフィギュレーションコード構成されたフィルタ、フィルタのデフォルト上記のすべての要求は、シーケンスを傍受されている2つのインターセプトされています。最初のロジックの側面は、傍受した後、フィルタの設定後インターセプトフィルタリングするように構成しました。私たちは、明示的に順序を指定したい場合はもちろん、あなたはの援助傍受することができます@Orderノートを。このコメントは、上で定義したクラスに追加されなければならないことに注意してください。

@Order(Ordered.LOWEST_PRECEDENCE - 2)
public class TimeConsumingCalculationFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
       //your logic
    }

}
@Order(Ordered.LOWEST_PRECEDENCE - 1)
public class TimeConsumingCalculationFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
       //your logic
    }

}

PS:@Order値、小さい実行優先度の値が大きいです。値が小さいほど、高い優先順位。我々は実行順序を定義する時以来、使用することをお勧めします@Order(Ordered.LOWEST_PRECEDENCE - 1)、それはより直感的に見えるような構成のこのフォームを、より大きなはOrdered.LOWEST_PRECEDENCEは、値が、高い優先度を差し引きます。

加えて、春も提供しOrderedFilterているインタフェースFilterOrderedインタフェースとの組み合わせを、そして原理は上記と同様です。あなたは状況を見ることができます。

このような構成の上記の利点、構成する非常に単純ですが、欠点も明らかにされ、デフォルトのロケーションインターセプトし、すべての要求に柔軟に十分ではありません。

第二の方法:@WebFilter方法

@WebFilter注釈は、サーブレットで提供ノートあり、春にもこのコメントをサポートしています。@WebFilterファイングレイン構成は、上記方法よりも柔軟であることができます。

@Configuration
public class WebConfig {
    //可以自定义url-pattern
    @WebFilter(urlPatterns="/*")
    @Order(Ordered.LOWEST_PRECEDENCE - 2)
    //这边如果不加`@Configuration`,需要通过`@ServletComponentScan`扫描`Listener`、`Filter`和`Servlet`这三个组件
    @Configuration
    public class TimeConsumingCalculationFilter implements Filter {

        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            //your logic
        }
    }   
    
    @WebFilter(urlPatterns="/*")
    @Order(Ordered.LOWEST_PRECEDENCE - 2)
    //这边如果不加`@Configuration`,需要通过`@ServletComponentScan`扫描`Listener`、`Filter`和`Servlet`这三个组件
    @Configuration
    public class TimeConsumingCalculationFilter2 implements Filter {

        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            //your logic
        }
    }   
    
}

@WebFilter注釈フィルタシンプルに配置され、カスタマイズ機能および切片のurl-patternシーケンス。

三つの方法:FilterRegistrationBean設定を使用して

@Configuration
public class WebConfig {

    private static Logger logger = LoggerFactory.getLogger(WebConfig.class);

    @Bean
        public FilterRegistrationBean<Filter> filter1() {
            FilterRegistrationBean<Filter> registrationBean = new FilterRegistrationBean<>();
            registrationBean.setName("filter1");
            registrationBean.setOrder(Ordered.LOWEST_PRECEDENCE - 2);
            registrationBean.setFilter(new TimeConsumingCalculationFilter());
            registrationBean.addUrlPatterns("/foo/*");
            return registrationBean;
        }
    
    
        @Bean
        public FilterRegistrationBean<Filter> filter2() {
            FilterRegistrationBean<Filter> registrationBean = new FilterRegistrationBean<>();
            registrationBean.setName("filter2");
            registrationBean.setOrder(Ordered.LOWEST_PRECEDENCE - 3);
            registrationBean.setFilter(new TimeConsumingCalculationFilter1());
            registrationBean.addUrlPatterns("/*");
            registrationBean.addInitParameter("key1","value1");
            registrationBean.addInitParameter("key2","value2");
            //通过Servlet name匹配Filter,不建议使用
            registrationBean.addServletNames("name1");
            return registrationBean;
        }

}

注意点:

  • それはFilterRegistrationBeanとフィルターの間に1対1の関係です。
  • そのユニークな名前を宣言してのsetName(文字列名)を呼び出すために、複数のFilterRegistrationBean必要がある場合は、そうでない場合のみ、最初に成功した登録が有効です。
  • 必要に応じて呼び出しシーケンスを確保するために、そのsetOrder(int型の順)メソッドを呼び出して設定することができます。

4つの方法:DelegatingFilterProxyRegistrationBean方法を使用して

@Configuration
public class WebConfig {
    
    @Bean("myFilter")
    //配置了DelegatingFilterProxyRegistrationBean后,这种方式配置的Filter不会生效了,只会拦截/foo/*的请求
    public Filter myFilter(){
        return new TimeConsumingCalculationFilter();
    }

    @Bean
    public DelegatingFilterProxyRegistrationBean delegatingFilterProxyRegistrationBean(){
        DelegatingFilterProxyRegistrationBean filterProxy = new DelegatingFilterProxyRegistrationBean("myFilter");
        filterProxy.addUrlPatterns("/foo/*");
        filterProxy.addInitParameter("targetFilterLifecycle","true");
        filterProxy.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico");
        filterProxy.setDispatcherTypes(DispatcherType.REQUEST);
        return filterProxy;
    }

}

FilterRegistrationBeanとDelegatingFilterProxyRegistrationBean違い:

  • onStartupメソッドを介して直接フィルタを登録FilterRegistrationBean。
  • DelegatingFilterProxyRegistrationBeanは豆を対応するフィルタを通過することによってカスタム・ルックアップのApplicationContextAwareインタフェースApplicationContextのインスタンス名を達成しながら、Servlet3.0 + DelegatingFilterProxy容器を登録し、そして豆を、対応するプロキシオブジェクトを生成します。

類推によって理解

  • カスタムサーブレット@WebServletまたはメソッドがServletRegistrationBeanを採用することができる追加
  • リスナーの方法はまた、@WebListenerまたはServletListenerRegistrationBeanを使用できるカスタムを追加し、イベントは一般的なモニターであることに注意してください

その他の関連カテゴリー

  • ServletComponentRegisteringPostProcessor
  • ServletComponentHandler
  • WebListenerHandler
  • WebFilterHandler
  • WebServletHandler

参照

  • https://blog.csdn.net/loveForever_xiang/article/details/101270633
  • https://www.liangzl.com/get-article-detail-121998.html
  • https://mp.weixin.qq.com/s/t8WdKEkYJuRApeEEOvXR_A
  • https://blog.csdn.net/andy_zhang2007/article/details/90399870
发布了184 篇原创文章 · 获赞 141 · 访问量 35万+

おすすめ

転載: blog.csdn.net/sinat_27535209/article/details/103960210