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