一、简介
1.1、概述
过滤器作为JavaWEB的三大组件(Servlet程序、Filter过滤器、Listener监听器),它的主要功能是用来拦截请求的,当客户端要访问某个资源时,先来到配置好的过滤器,过滤器可以在用户访问某个资源之前或者之后做一些事情,例如:
(1)校验请求的参数是否符合逻辑,符合逻辑则放行,不符合逻辑则不允许访问方法;
(2)设置 请求/响应 的Header;
(3)修改 请求/响应 的内容;
......
另外,Filter引入了过滤器链(Filter Chain)的概念,一个Web应用可以部署多个Filter,由这些Filter组成一种链式结构,共同处理客户端的请求,当客户端的请求到达Servlet之前会先在这个链上传递,不同的Filter负责处理不同的 请求/响应。
1.2、流程图
1.3、多个Filter的执行特点
(1)所有的filter和目标资源默认都执行在同一个线程中;
(2)多个filter共同执行的时候,它们使用同一个request对象;
(3)在多个Filter执行的时候,它们的优先级顺序是按照web.xml中配置的顺序执行的,配置在上面的先执行;
1.4、 doFilter()的作用
(1)执行下一个Filter过滤器(如果有的话);
(2)执行目标资源(只有一个过滤器);
二、创建 & 使用过滤器
2.1、说明
由于当前公司的日常主流技术是springboot + 微服务,所以原始的JavaWEB中的方式,我这边暂时先不演示了,等以后有时间再补充!这里主要演示在springboot中如何创建 & 使用过滤器;参考:SpringBoot 过滤器 filter 3种方法_springboot 全局filter_饼干开发的博客-CSDN博客
2.2、@WebFilter + @ServletComponentScan
2.2.1、步骤
(1)创建一个类实现Filter接口;
(2)类上添加@WebFilter(urlPatterns = "") 注解,在chain.doFilter()中编写拦截逻辑;
(3)配置类上添加 @ServletComponentScan 注解,将标识了 @WebServlet、@WebFilter、@WebListener 注解的类注入到IOC容器中;
2.2.2、@WebFilter
@WebFilter是javax包中提供的一个注解,标识在实现Filter接口的类上,表明该类是一个过滤器类,通常搭配 urlPatterns 属性一起使用,如下所示:
@WebFilter(urlPatterns = "/user/*")
@Slf4j
public class LoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
}
@Override
public void destroy() {
}
}
2.2.3、@ServletComponentScan
@ServletComponentScan是springboot提供的一个注解,一般标识在配置类上,用于将类上标识了 @WebServlet、@WebFilter、@WebListener 注解的类注入到IOC容器中。例如:
@ServletComponentScan
@SpringBootApplication
public class SpringbootFilterApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootFilterApplication.class, args);
}
}
2.2.4、小总结
@WebFilter注解标识在实现Filter接口的类上,表明该类是一个过滤器类,通常搭配 urlPatterns 属性一起使用, @ServletComponentScan注解一般标识在配置类上,用于将类上标识了 @WebServlet、@WebFilter、@WebListener 注解的类注入到IOC容器中,两者搭配使用提供过滤功能,上面配置的loginFilter,当用户访问 /user/login 接口时,会先执行 LoginFilter中
的doLogin()方法,当执行chain.doFilter(request, response)后,才会真正执行 /user/login 中的业务。
2.3、FilterRegistrationBean
2.3.1、步骤
(1)编写一个类实现Filter;
@Slf4j
public class AuthorityFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
}
@Override
public void destroy() {
}
}
(2)配置类中注册Filter;
/**
* @Author : 一叶浮萍归大海
* @Date: 2023/11/5 1:59
* @Description:
*
* 注意事项:
* 此处也可以不写此配置,不写的话,AuthorityFilter由于加了@Component注解,也会被Spring容器管理,但是@Component注解没有路径过滤规则,
* 即会将所有请求都过滤,配置的意义主要就是为了过滤某一类的请求,如下的配置是只有访问以 /privilege/* 打头的请求才会过滤,访问其他的则不过滤
*/
@Configuration
public class MyFilterConfig {
@Bean
public FilterRegistrationBean registrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new AuthorityFilter());
registrationBean.setName("authorityFilter");
registrationBean.addUrlPatterns("/privilege/*");
// 值越小,优先级越高
registrationBean.setOrder(1);
return registrationBean;
}
}