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