1. 程式人生 > >SpringBoot自定義過濾器的兩種方式及過濾器執行順序

SpringBoot自定義過濾器的兩種方式及過濾器執行順序

第一種 @WebFilter + @ServletComponentScan 註解

1、首先自定義過濾器

如下自定義過濾器 ReqResFilter 必須實現  javax.servlet.Filter。然後添加註解 @WebFilter(javax.servlet.annotation.WebFilter),urlPatterns 過濾器要過濾的URL規則配置,filterName 過濾器的名稱。

@Order(int) 註解,配合 @WebFilter 註解使用,用於多個過濾器時定義執行順序,值越小越先執行。

記住上面這句話,稍後再說。

//@Order(1)
@WebFilter(urlPatterns = "*.json", filterName = "reqResFilter")
public class ReqResFilter implements Filter {

    private static Logger logger = LoggerFactory.getLogger(ReqResFilter.class);
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) 
                 throws IOException, ServletException { System.out.println("11111111111111111111111111111"); filterChain.doFilter(servletRequest,servletResponse); } @Override public void destroy() { } }

 2、新增 @ServletComponentScan 註解

然後在啟動類上加一個註解 @ServletComponentScan 就可以了,然後啟動springboot 訪問你的介面就會看到列印過濾器裡的內容了。

3、多個過濾器如何指定執行順序?

剛才說了,使用@Order註解指定一個int值,越小越先執行。很多部落格文章都是這麼說的,但你真正的試了嗎?真的可以使用這個註解指定順序嗎?答案是否定的。

經過測試,發現 @Order 註解指定 int 值沒有起作用,是無效的。為啥?因為看原始碼發現 @WebFilter 修飾的過濾器在載入時,沒有使用 @Order 註解,而是使用的類名來實現自定義Filter順序,詳細的可以參考這篇或者是這篇

所以這種方式下想定義Filter的順序,就必須限定 Filter 的類名,比如剛才那個 Filter 叫 ReqResFilter ,加入我們現在新寫了一個 Filter 叫 AlibabaFilter ,那麼順序就是 AlibabaFilter > ReqResFilter 。

所以這種方式雖然實現起來簡單,只需要註解,但自定義順序就必須要限定類名,使用類名達到排序效果了。

如果要實現自定義順序,就用下面這種。

第二種 自定義配置類配置過濾器

1、單個過濾器時

1、自定義配置類載入自定義過濾器 ReqResFilter 

 還是剛才那個自定義過濾器,只不過上面的兩個註解都可以去掉了。

@Configuration
public class WebConfig {
    @Bean
    public FilterRegistrationBean timeFilter() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        ReqResFilter reqResFilter = new ReqResFilter();
        filterRegistrationBean.setFilter(reqResFilter);
     filterRegistrationBean.addUrlPatterns("*.json");//配置過濾規則
     return filterRegistrationBean;
  } 
}

 

2、確保 WebConfig 類能被掃描到就可以了,然後啟動springboot 訪問你的介面就會看到列印過濾器裡的內容了。

3、多個過濾器時如何配置

多個過濾器,怎麼配置,都寫在一個 FilterRegistrationBean 裡嗎?配置執行順序怎麼配置?過濾器名稱怎麼配置

新增一個過濾器

如下,新增一個過濾器 ReqResFilter1

public class ReqResFilter1 implements Filter {
    private static Logger logger = LoggerFactory.getLogger(ReqResFilter1.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //獲取 filterRegistrationBean.addInitParameter("name","hahahhhaa")設定的引數
        System.out.println("init=============="+filterConfig.getInitParameter("name"));
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("2222222222222222222222222222");
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {
    }
}

 

修改配置類

現在我們有兩個過濾器 ReqResFilter 和 ReqResFilter1 ,怎麼設定執行順序。請看下面的程式碼。

這裡我們,咋 WebConfig 類裡再寫一個 reqResFilter1 方法註冊新增的這個過濾器。和剛才不同的是我們指定了 多個過濾器的 Order 即執行順序,ReqResFilter1 的 Order 為2,設定 ReqResFilter  的Order為1。

@Configuration
public class WebConfig {

    @Bean
    public FilterRegistrationBean reqResFilter1() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();

        ReqResFilter1 reqResFilter1 = new ReqResFilter1();

        filterRegistrationBean.setFilter(reqResFilter1);
        filterRegistrationBean.addUrlPatterns("*.json");//配置過濾規則
        filterRegistrationBean.addInitParameter("name","hahahhhaa");//設定init引數
        filterRegistrationBean.setName("reqResFilter1");//設定過濾器名稱
        filterRegistrationBean.setOrder(2);//執行次序

        return filterRegistrationBean;
    }

    @Bean
    public FilterRegistrationBean reqResFilter() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();

        ReqResFilter reqResFilter = new ReqResFilter();

        filterRegistrationBean.setFilter(reqResFilter);

        //配置多個過濾規則
//        List<String> urls = new ArrayList<>();
//        urls.add("/order/*");
//        urls.add("/user/*");
//        filterRegistrationBean.setUrlPatterns(urls);

        filterRegistrationBean.addUrlPatterns("*.json");//配置過濾規則
        filterRegistrationBean.setName("reqResFilter");//設定過濾器名稱
        filterRegistrationBean.setOrder(1);//執行次序

        return filterRegistrationBean;
    }
}

 

另外  filterRegistrationBean.addInitParameter("name","hahahhhaa");//設定init引數 設定的引數在 Filter 的init 方法裡的 FilterConfig 物件裡可以獲取到,即 filterConfig.getInitParameter("name")

 

另外 filterRegistrationBean.setUrlPatterns(urls); 可以設定多個URL匹配規則,setUrlPatterns接收一個List<String>型別的引數

當不設定 setOrder 次序時,過濾器的執行順序預設是 Bean 的載入順序。在當前 WebConfig 類中,先載入的是 reqResFilter1方法 即 ReqResFilter1 過濾器,後加載的是 reqResFilter 方法 即 ReqResFilter 過濾器。

&n