在Springboot中使用Filter有兩種方式,注解@WebFilter方式和注冊bean方式;
一、注解@WebFilter方式
1. 實現Filter接口(javax.servlet);
2. 添加@WebFilter注解;
3. 啟動類添加@ServletComponmentScan注解;
附上代碼:
第一個Filter
@Slf4j @WebFilter(filterName = "filter1", urlPatterns = {"/url1/*"}) public class Filter1_Filter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { log.info("do filter1"); filterChain.doFilter(servletRequest, servletResponse); } @Override public void destroy() { } }
第二個Filter
@Slf4j @WebFilter(filterName = "filter2", urlPatterns = {"/url2/*"}) public class Filter2_Filter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { log.info("do filter2"); filterChain.doFilter(servletRequest, servletResponse); } @Override public void destroy() { } }
啟動類:
@SpringBootApplication @ServletComponentScan public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication .class, args); } }
下面說說我踩過的坑:
1. 不加@ServletComponentScan注解無法注入Filter,這個注解的作用就是去掃描@WebServlet、@WebFilter、@WebListener這類特殊注解。如果不加,spring容器是不會主動掃描的
2. 多個Filter的執行順序,說出來你可能不信,這種注解方式實現的Filter是通過Filter的類名首字母來控制執行順序的,像Filter1_Filter就比Filter2_Filter先執行。但網上一些資料說,當Filter數量很多時,是沒有明確的執行順序的,所以這種方式還是放棄吧,推薦第二種。
二、注冊bean的方式
1、實現Filter接口
2、注冊Filter
下面附上代碼,第一個Filter:
@Slf4j public class Filter1 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { log.info("do filter1"); filterChain.doFilter(servletRequest, servletResponse); } @Override public void destroy() { } }
第二個Filter:
@Slf4j public class Filter2 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { log.info("do filter2"); filterChain.doFilter(servletRequest, servletResponse); } @Override public void destroy() { } }
注冊類:
@Configuration public class FilterConfig { @Bean public Filter filter1(){ return new Filter1(); } @Bean public Filter filter2(){ return new Filter2(); } @Bean public FilterRegistrationBean setFilter1() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); filterRegistrationBean.setFilter(filter1()); filterRegistrationBean.addUrlPatterns("/url1/*"); filterRegistrationBean.setOrder(1); //order的數值越小,在所有的filter中優先級越高 return filterRegistrationBean; } @Bean public FilterRegistrationBean setFilter2(){ FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); filterRegistrationBean.setFilter(filter2()); filterRegistrationBean.addUrlPatterns("/url2/*"); filterRegistrationBean.setOrder(2); //order的數值越小,在所有的filter中優先級越高 return filterRegistrationBean; } }
這種方式就比較嚴謹了,通過filterRegistrationBean.setOrder(1)設置執行順序親測有效。
注意:
SpringBootApplication上使用@ServletComponentScan注解后,Servlet、Filter、Listener
可以直接通過@WebServlet、@WebFilter、@WebListener注解自動注冊,無需其他代碼。