Web 三大组件之Filter
今天我们来讨论一下什么是Filter(过滤器),以及它可以用来干嘛,最后我们如何通过代码来进行实现
1. 什么是Filter
我们知道,浏览器和服务器进行交互的时候,肯定避免不了发送Http请求,那么请求到达后端controller接口的过程中,其实我们可以设定一层拦截,这层拦截其实就是过滤器啦。形象一点说,它就像是一条河的大坝,我们可以进行拦截。
2. Filter有哪些实际作用呢
- 日志记录: 这是最常见的,我们去记录方法的执行时间,请求参数,相应参数等等
- 权限控制: 由于Filter可以对于过来的请求进行放行或者遣返,因此我们可以对于过来的请求进行相关校验,决定请求放行与否
- 跨域处理: 我们知道前后端分离的项目很容易发生跨域问题,在Filter中也可以去解决
3. Filter如何来实现呢
话不多说,我们直接看代码会更加形象,这里我们列举两种在springboot项目中如何简单去实现 filter
1. 通过@WebFilter注解简单实现
-
首先第一步,我们要撰写一个自定义的Filter类,实现Filter接口,实现后会发现我们要重写3个方法
init 该方法是filter初始化时候执行,一般不太需要去实现它 destroy 该方法是filter被销毁时候执行,一般来说只有我们的应用程序关闭时候,这个方法才会触发 doFilter 这是最重要的方法,这个方法可以获取请求途中的request, response,以及一个filterChain, 前两个参数我们可以做一些记录,然后,只要我们调用了filterChain.doFilter(servletRequest, servletResponse) 方法,这个请求才会被放行到Controller层 @WebFilter注解中需要的参数如下
属性名 类型 描述 filterName String 指定过滤器的 name 属性 value String[] 该属性等价于 urlPatterns 属性。但是两者不应该同时使用。 urlPatterns String[] 指定一组过滤器的 URL 匹配模式。等价于 标签。 servletNames String[] 指定过滤器将 应用于哪些 Servlet。取值是 @WebServlet 中的 name 属性的取值,或者是 web.xml 中 的取值。 dispatcherTypes DispatcherType 指定过滤器的转发模式。具体取值包括:ASYNC、ERROR、FORWARD、INCLUDE、REQUEST。 initParams WebInitParam[] 指定一组过滤器初始化参数,等价于 标签。 asyncSupported boolean 声明过滤器是否支持异步操作模式,等价于 标签。 description String 该过滤器的描述信息,等价于 标签。 displayName String 该过滤器的显示名,通常配合工具使用,等价于 标签。
@Slf4j
@WebFilter(urlPatterns = "/*", filterName = "myFilter", asyncSupported = true)
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("MyFilter 初始化成功啦。。。");
}
@Override
public void destroy() {
log.info("MyFilter 销毁成功了。。。");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
filterChain.doFilter(servletRequest, servletResponse);
}
}
重点来了,这种方式在使用的时候一定要在启动类上加上@ServletComponentScan, 否则不会生效,切记
以上就是Filter的第一种使用姿势了,但是它会有一个弊端,就是我们无法去指定各个Filter之间的优先级,那这种情况怎么办呢,可以使用第二种方式
2. 通过FilterRegistrationBean 把我们定义的Filter注入到spring容器中
其中这个order属性的值约小,代表优先级就越高
@SpringBootApplication
@ServletComponentScan
public class SpringTestProject implements WebMvcConfigurer {
public static void main(String[] args) {
SpringApplication.run(SpringTestProject.class, args);
}
@Bean
public FilterRegistrationBean<Filter> registrationBean() {
FilterRegistrationBean<Filter> filter = new FilterRegistrationBean<>();
filter.setName("myFilter2");
filter.setFilter(new MyFilter2());
filter.setOrder(-1);
return filter;
}
}