文章目录

  • 文章参考
  • 什么是过滤器
  • filter 特点
  • 自定义filter的方式
  • 第一种:直接实现Filter接口,并使用@Component注解标注为组件自动注入bean
  • 第二种:实现Filter接口,用@WebFilter注解
  • 第三种:既使用@Component同时也使用@WebFilter

文章参考

SpringBoot系列——Filter 过滤器

  1. springboot 过滤器Filter vs 拦截器Interceptor vs 切片Aspect 详解

什么是过滤器

过滤器依赖于servlet容器,只能在 servlet容器,web环境下使用

filter 特点

  • Filter 接口定义在 javax.servlet 包中
  • Filter 定义在 web.xml 中
  • Filter在只在 Servlet 前后起作用。Filters 通常将 请求和响应(request/response) 当做黑盒子,Filter 通常不考虑servlet 的实现
  • Filter 是 Servlet 规范规定的。
  • Filter 是在 Servlet 规范中定义的,是 Servlet 容器支持的
  • Filter 不能够使用 Spring 容器资源
  • Filter 是被 Server(like Tomcat) 调用

filter 和 interceptor 触发时机

自定义filter的方式

第一种:直接实现Filter接口,并使用@Component注解标注为组件自动注入bean

默认是针对所有的请求路径,即 “\*”

package com.huangbiao.springbootweb.config.filters;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

/**
 * Created by toutou on 2018/10/27.
 */
@Slf4j
@Component
public class MyTestFilter implements Filter{

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
    System.out.println("1111111111111111111111111");
    log.info("filter 初始化");
  }

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    throws IOException, ServletException {
    // TODO Auto-generated method stub
    System.out.println("2222222222222222222222222");
    log.info("doFilter 请求处理");
    //TODO 进行业务逻辑

    //链路 直接传给下一个过滤器
    chain.doFilter(request, response);
  }

  @Override
  public void destroy() {
    System.out.println("33333333333333333333333333");
    log.info("filter 销毁");
  }
}

如何配置路径?
添加一个方法返回 FilterRegistrationBean 的配置,使用 @Bean 注解交给spring容器管理

package com.huangbiao.springbootweb.config;

import com.huangbiao.springbootweb.config.interceptor.LogInterceptor;
import com.huangbiao.springbootweb.config.interceptor.LoginInterceptor;
import com.huangbiao.springbootweb.config.filters.MyTestFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class SpringWebConfig extends WebMvcConfigurerAdapter {

  // 添加自定义拦截器
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addWebRequestInterceptor(new LogInterceptor());
    // 如果没有设置匹配路径,则针对所有请求都有效
    // registry.addInterceptor(new LocaleChangeInterceptor());
    registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/person/*");
  }

  // @Bean 是交给spring容器管理,方法就是 xml 配置的id, 返回值类型就是定义的实例化类型
  @Bean
  public FilterRegistrationBean testFilterRegistration(MyTestFilter myTestFilter) {
    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(myTestFilter);//添加过滤器
    registration.addUrlPatterns("/show");//设置过滤路径,/*所有路径
    //registration.addInitParameter("name", "alue");//添加默认参数
    registration.setName("MyFilter");//设置优先级
    registration.setOrder(1);//设置优先级
    return registration;
  }

}

第二种:实现Filter接口,用@WebFilter注解

  1. @WebFilter 指定拦截路径以及一些参数
package com.huangbiao.springbootweb.config.filters;

import lombok.extern.slf4j.Slf4j;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@Slf4j
//配置拦截路径
@WebFilter(filterName = "testFilter",urlPatterns = {"/person/*"})
public class MyWebFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("MyWebFilter 初始化");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("MyWebFilter doFilter");
    }

    @Override
    public void destroy() {
        log.info("MyWebFilter destroy");
    }
}
  1. 同时需要在启动类使用@ServletComponentScan扫描带@WebFilter、@WebServlet、@WebListener并将帮我们注入bean
package com.huangbiao.springbootweb;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@SpringBootApplication
// 详细到mapper父级目录
//@MapperScan("com.huangbiao.springbootweb.hello.mapper")
// 全局项目
@MapperScan("com.huangbiao.springbootweb")
//@ServletComponentScan("com.huangbiao.springbootweb.config.filter")
//自动扫描与当前类的同包以及子包
@ServletComponentScan
public class SpringbootwebApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootwebApplication.class, args);
    }

}

第三种:既使用@Component同时也使用@WebFilter

同时需要在启动类使用@ServletComponentScan扫描带@WebFilter、@WebServlet、@WebListener并将帮我们注入bean

package com.huangbiao.springbootweb.config.filters;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@Slf4j
//配置拦截路径
@WebFilter(filterName = "MyWebFilterComponent",urlPatterns = {"/person/*"})
@Component
public class MyWebFilterComponent implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("MyWebFilterComponent init");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("MyWebFilterComponent doFilter");
    }

    @Override
    public void destroy() {
        log.info("MyWebFilterComponent destroy");
    }
}
package com.huangbiao.springbootweb;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@SpringBootApplication
// 详细到mapper父级目录
//@MapperScan("com.huangbiao.springbootweb.hello.mapper")
// 全局项目
@MapperScan("com.huangbiao.springbootweb")
//@ServletComponentScan("com.huangbiao.springbootweb.config.filter")
//自动扫描与当前类的同包以及子包
@ServletComponentScan
public class SpringbootwebApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootwebApplication.class, args);
    }

}