在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注解自动注册,无需其他代码。