第一種 @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 reqResFilter() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); ReqResFilter reqResFilter = new ReqResFilter(); filterRegistrationBean.setFilter(reqResFilter);
filterRegistrationBean.addUrlPatterns("*.json");//配置過濾規則
return filterRegistrationBean;
}
}
2、確保 WebConfig 類能被掃描到就可以了,然后啟動springboot 訪問你的接口就會看到打印過濾器里的內容了。
2、多個過濾器時如何配置
多個過濾器,怎么配置,都寫在一個 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 過濾器。
3、SpringBoot注冊第三方過濾器
假如我們在項目里引入了第三方的jar,要使用jar里面帶的 Filter 的話,如果引用的某個jar包中的過濾器,且這個過濾器在實現時沒有使用 @Component
標識為Spring Bean,則這個過濾器將不會生效。此時需要通過java代碼去注冊這個過濾器。也是使用該種方式進行注冊。