1. 程式人生 > >Springboot使用Filter以及踩過的坑

Springboot使用Filter以及踩過的坑

Springboot使用Filter以及踩過的坑

在Springboot中使用Filter有兩種方式,註解方式,註冊bean方式

一、註解@WebFilter

1、實現Filter介面(javax.servlet)

2、新增@WebFilter註解

3、啟動類新增@ServletComponentScan註解

附上程式碼:

第一個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)設定執行順序親測有效