SpringBoot 配置过滤器 Filter

SpringBoot 配置过滤器 Filter

文章目录

  !版权声明:本博客内容均为原创,每篇博文作为知识积累,写博不易,转载请注明出处。


相关地址:

  • Spring Servlet 文档:https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/web/servlet
  • 示例项目 Github:https://github.com/my-dlq/blog-example/tree/master/springboot/springboot-filter-example

系统环境:

  • Jdk 版本:jdk 8
  • SpringBoot 版本:2.2.1.RELEASE

一、什么是过滤器

javax.servlet.Filter 是一个接口,可以动态地拦截请求和响应信息,以变换或使用包含在请求或响应中的信息。

二、过滤器使用场景

  • 数据压缩
  • 记录日志
  • 数据统计
  • 数据格式转换
  • 数据设置默认值
  • 权限认证、黑白名单
  • 数据加密/解密、签名效验

三、过滤器流程原理

在一个 web 应用中,可以开发编写多个 Filter,这些 Filter 组合起来称之为一个 Filter 链。在用户发起请求后,请求信息会根据过滤器链中过滤器的顺序进入各个过滤器,每经过一层过滤器时,需要通过这些滤器验证逻辑通过后放行,才能进入下一个过滤器,直至到服务器获取资源。等到服务器获取资源成功后进行响应给过滤器,然后再倒序的方式,经过一层层过滤器,最后对用户进行响应。

四、过滤器分类

Servlet 2.5:

  • REQUEST:用户直接访问页面时,WEB 容器将会调用过滤链。
  • FORWARD:目标资源是通过 RequestDispatcher 的 forward 访问时,该过滤器将被调用。
  • INCLUDE:目标资源是通过 RequestDispatcher 的 include 方法调用时,过滤器将被调用。
  • ERROR:目标资源是通过声明式异常处理机制调用时,过滤链将被调用。

Servlet 3.0:

  • ASYNC:支持异步处理。

五、过滤器中实现的方法

  • public void doFilter (ServletRequest, ServletResponse, FilterChain)

该方法完成实际的过滤操作,当客户端请求方法与过滤器设置匹配的 URL 时,Servlet 容器将先调用过滤器的 doFilter 方法。FilterChain 用户访问后续过滤器。

  • public void init(FilterConfig filterConfig)

web 应用程序启动时,web 服务器将创建Filter 的实例对象,并调用其init方法,完成对象的初始化功能(filter对象只会创建一次,init方法也只会执行一次)。开发人员通过init方法的参数,做一些初始化操作,例如读取配置文件等。

  • public void destroy()

Servlet 容器在销毁过滤器实例前调用该方法,在该方法中释放Servlet过滤器占用的资源。

六、两种创建过滤器方式

方式一:过滤器注解方式

创建步骤:

  • (1)、创建过滤器类实现 Filter 接口,并在类的上面添加 @WebFilter 注解。
  • (2)、过滤器类上添加 @Order() 注解来制定过滤器的顺序。
  • (3)、SpringBoot 启动类上添加 @ServletComponentScan 注解。

实现过滤器接口,并添加 @WebFilter 与 @Order 注解,配置过滤器:

 1@Order(1)
 2@WebFilter(filterName = "myFilter", urlPatterns = {"*"})
 3public class MyCustomFilter2 implements Filter {
 4    @Override
 5    public void init(FilterConfig filterConfig) throws ServletException {}
 6    @Override
 7    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) {}
 8    @Override
 9    public void destroy() {}
10}

启动类添加 @ServletComponentScan 注解:

1@SpringBootApplication
2@ServletComponentScan
3public class Application {
4    public static void main(String[] args) {
5        SpringApplication.run(Application.class, args);
6    }
7}

方式二:过滤器注册 Bean 方式

创建步骤:

  • (1)、创建过滤器类实现 Filter 接口。
  • (2)、创建过滤器配置类,里面创建一个过滤器注册 Bean,将之前创建的过滤器注册到其中。

创建过滤器类实现 Filter 接口:

1public class MyCustomFilter1 implements Filter {
2    @Override
3    public void init(FilterConfig filterConfig) throws ServletException {}
4    @Override
5    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain){}
6    @Override
7    public void destroy() {}
8}

创建过滤器配置类,里面创建一个过滤器注册 Bean,将之前创建的过滤器注册到其中:

1@Bean
2public FilterRegistrationBean customFilter(){
3    FilterRegistrationBean<MyCustomFilter1> filterBean = new FilterRegistrationBean<>();
4    filterBean.setFilter(new MyCustomFilter1());
5    filterBean.setName("FilterController");
6    filterBean.addUrlPatterns("/*");
7    return filterBean;
8}

七、注解方式创建过滤器

1、参数说明

@WebFilter 能配置很多过滤器参数,下面是部分参数介绍:

参数名称 参数类型 参数描述
filterName String Filter 名称
displayName String Filter 的显示的名称
asyncSupported boolean 设置 Filter 是否支持异步模式
initParams WebInitParam[] 可以在初始化时配置一些参数
servletNames String[] 设置对哪些 Servlet 进行过滤
urlPatterns String[] 指定拦截的路径
value String[] 和urlPatterns属性作用相同,都是指定拦截的路径,两种配置其一即可
dispatcherTypes DispatcherType[] 设置 Filter 对哪种方式的请求进行过滤,支持的属性任如下:
ASYNC、 ERROR、FORWARD、INCLUDE、REQUEST
(默认过滤所有方式的请求)

2、使用示例

(1)、创建 Controller 类

 1import org.springframework.web.bind.annotation.GetMapping;
 2import org.springframework.web.bind.annotation.RestController;
 3
 4@RestController
 5public class TestController {
 6
 7    @GetMapping("/aa/hello")
 8    public String hello1(){
 9        return "hello world! aa";
10    }
11
12    @GetMapping("/bb/hello")
13    public String hello2(){
14        return "hello world! bb";
15    }
16
17    @GetMapping("/cc/hello")
18    public String hello3(){
19        return "hello world! cc";
20    }
21
22}

(2)、创建 Filter 类

 1import javax.servlet.*;
 2import java.io.IOException;
 3import javax.servlet.FilterChain;
 4import javax.servlet.ServletException;
 5import javax.servlet.ServletRequest;
 6import javax.servlet.ServletResponse;
 7import javax.servlet.annotation.WebFilter;
 8import org.springframework.core.annotation.Order;
 9
10/**
11 * 自定义过滤器(注解方式)
12 */
13@Order(1)
14@WebFilter(filterName = "myFilter", urlPatterns = {"/aa/*", "/bb/*"}, description = "自定义过滤器")
15public class MyCustomFilter2 implements Filter {
16
17    @Override
18    public void init(FilterConfig filterConfig) throws ServletException {
19        System.out.println("过滤器初始化");
20    }
21
22    @Override
23    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
24        System.out.println("before ...");
25        // 过滤器放行
26        filterChain.doFilter(servletRequest, servletResponse);
27        System.out.println("after ...");
28    }
29
30    @Override
31    public void destroy() {
32        System.err.println("过滤器销毁");
33    }
34
35}

(3)、创建启动类

 1import org.springframework.boot.SpringApplication;
 2import org.springframework.boot.autoconfigure.SpringBootApplication;
 3import org.springframework.boot.web.servlet.ServletComponentScan;
 4
 5@SpringBootApplication
 6@ServletComponentScan
 7public class Application {
 8
 9    public static void main(String[] args) {
10        SpringApplication.run(Application.class, args);
11    }
12
13}

八、过滤器注册 Bean 方式创建过滤器

1、方法参数说明

方法名称 方法描述
setName() 设置过滤器名称
setFilter() 设置要注册的过滤器
setOrder() 设置过滤器的顺序位置
setAsyncSupported() 设置 Filter 是否支持异步模式
addUrlPatterns() 增加拦截的拦截
setUrlPatterns() 设置拦截的路径
addServletNames() 为过滤器增加servlet名称
setServletNames() 设置注册过滤器的servlet名称
setInitParameters() 设置初始化参数
addInitParameter() 增加初始化参数
setMatchAfter() 设置是否在ServletContext的任何声明的过滤器映射之后匹配过滤器映射
setDispatcherTypes() 设置 Filter 对哪种方式的请求进行过滤,支持的属性任如下:
ASYNC、 ERROR、FORWARD、INCLUDE、REQUEST
(默认过滤所有方式的请求)

2、创建步骤

  • (1)、创建过滤器类实现 Filter 接口。
  • (2)、创建过滤器配置类,里面创建一个过滤器注册 Bean,将之前创建的过滤器注册到其中。

3、使用示例

(1)、创建 Controller 类

 1import org.springframework.web.bind.annotation.GetMapping;
 2import org.springframework.web.bind.annotation.RestController;
 3
 4@RestController
 5public class TestController {
 6
 7    @GetMapping("/aa/hello")
 8    public String hello1(){
 9        return "hello world! aa";
10    }
11
12    @GetMapping("/bb/hello")
13    public String hello2(){
14        return "hello world! bb";
15    }
16
17    @GetMapping("/cc/hello")
18    public String hello3(){
19        return "hello world! cc";
20    }
21
22}

(2)、创建 Filter 类

 1import javax.servlet.*;
 2import javax.servlet.FilterConfig;
 3import java.io.IOException;
 4
 5/**
 6 * 自定义过滤器(配置 Bean 方式)
 7 */
 8public class MyCustomFilter1 implements Filter {
 9
10    @Override
11    public void init(FilterConfig filterConfig) throws ServletException {
12        System.out.println("过滤器初始化");
13    }
14
15    @Override
16    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
17        System.out.println("before ...");
18        // 过滤器放行
19        filterChain.doFilter(servletRequest, servletResponse);
20        System.out.println("after ...");
21    }
22
23    @Override
24    public void destroy() {
25        System.err.println("过滤器销毁");
26    }
27
28}

(3)、创建 Filter 配置类

 1import org.springframework.boot.web.servlet.FilterRegistrationBean;
 2import org.springframework.context.annotation.Bean;
 3import org.springframework.context.annotation.Configuration;
 4
 5@Configuration
 6public class FilterConfig {
 7
 8    /**
 9     * 代码方式注册Bean
10     * @return
11     */
12    @Bean
13    public FilterRegistrationBean customFilter(){
14        FilterRegistrationBean<MyCustomFilter1> filterBean = new FilterRegistrationBean<>();
15        filterBean.setFilter(new MyCustomFilter1());
16        filterBean.setName("FilterController");
17        filterBean.addUrlPatterns("/cc/*","/bb/*");
18        return filterBean;
19    }
20
21}

(4)、创建启动类

 1import org.springframework.boot.SpringApplication;
 2import org.springframework.boot.autoconfigure.SpringBootApplication;
 3import org.springframework.boot.web.servlet.ServletComponentScan;
 4
 5@SpringBootApplication
 6@ServletComponentScan
 7public class Application {
 8
 9    public static void main(String[] args) {
10        SpringApplication.run(Application.class, args);
11    }
12
13}

---END---


  !版权声明:本博客内容均为原创,每篇博文作为知识积累,写博不易,转载请注明出处。