Spring Boot 自定义过滤器(Filter)
Filter 过滤器主要是用来过滤用户请求的,它允许我们对用户请求进行前置处理和后置处理,比如实现 URL 级别的权限控制、过滤非法请求等等。Filter 过滤器是面向切面编程——AOP 的具体实现(AOP切面编程只是一种编程思想而已)。
自定义 Filter 只需要实现
import javax.servlet.Filter
接口即可。Filter 接口依赖于 Servlet 容器,
Filter
接口就在 Servlet 包下,属于 Servlet 规范的一部分。
javax.servlet.Filter
public interface Filter {
//初始化过滤器后执行的操作
default void init(FilterConfig filterConfig) throws ServletException {
}
// 对请求进行过滤
void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
// 销毁过滤器后执行的操作,主要用户对某些资源的回收
default void destroy() {
}
}
Filter 是如何实现拦截的?
通过
FIlter
接口中的
doFilter
方法,实现了对用户请求的过滤,其中请求流程为
- 用户发送请求到 web 服务器,请求会先到过滤器;
- 过滤器会对请求进行一些处理比如过滤请求的参数、修改返回给客户端的 response 的内容、判断是否让用户访问该接口等等。
- 用户请求响应完毕。
- 进行一些自己想要的其他操作。
Spring Boot 自定义过滤器(Filter)
自定义 Filter 的方法
提供两种方法
1. 通过 手动注册配置实现
MyFilter
实现了
javax.servlet.Filter
package com.zwk.spring_boot_filter_listener.util;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* @description:
* @author: zwk
* @date: 2021/6/10
*/
@Component
public class MyFilter implements Filter {
Logger log = LoggerFactory.getLogger(MyFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
System.out.println("init");
log.info("init");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setAttribute("filter", " doFilter");
log.info("doFilter");
System.out.println("请求接口为:" + ((HttpServletRequest) servletRequest).getRequestURI());
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
Filter.super.destroy();
log.info("destroy");
}
}
MyFilterConfig.java
将 Filter 注册
之所使用 @Bean + FilterRegistrationBean 的方式注册Filter 是为了更灵活的设置映射。
当然,也可以不使用 @Bean + FilterRegistrationBean 的方式注册,即使用基于约定的映射:
/*
。直接创建自定义 Filter 并且注册为 Spring 的组件即可。
@Configuration
public class MyFilterConfig {
@Autowired
MyFilter myFilter;
@Bean
public FilterRegistrationBean<MyFilter> thirdFilter() {
FilterRegistrationBean<MyFilter> filterRegistrationBean = new FilterRegistrationBean<>();
// 注册自定义的 Filter
filterRegistrationBean.setFilter(myFilter);
// 设置拦截 Url映射
filterRegistrationBean.setUrlPatterns(new ArrayList<>(Arrays.asList("/api/*")));
return filterRegistrationBean;
}
}
2. 通过注解实现
在自己的过滤器的类上加上
@WebFilter
然后在这个注解中通过它提供好的一些参数进行配置。
@WebFilter(filterName = "MyFilterWithAnnotation", urlPatterns = "/api/*")
public class MyFilterWithAnnotation implements Filter {
......
}
注意
另外,为了能让 Spring 找到它,你需要在启动类上加上
@ServletComponentScan
注解
控制多个 Filter 的执行顺序
通过 @Order 注解,控制 顺序
通过将 @Order 注解 放置于 Filter 实现类上调整 value 的值控制执行顺序(value越小优先级越高)
@Order(1)
public class MyFilter implements Filter {
......
}
下例优先级低于上例
@Order(2)
public class MyFilter2 implements Filter {
......
}
注意
: 这种方式适用于,不使用 @Bean + FilterRegistrationBean 注册的Filter。
当需要使用 @Bean + FilterRegistrationBean 注册 Filter 时则可以使用
FilterRegistrationBean
的
setOrder(int value)
方法
package com.zwk.spring_boot_filter_listener.config;
import com.zwk.spring_boot_filter_listener.util.MyFilter;
import com.zwk.spring_boot_filter_listener.util.MyFilter2;
import java.util.ArrayList;
import java.util.Arrays;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @description:
* @author: zwk
* @date: 2021/6/10
*/
@Configuration
public class MyFilterConfig {
final
MyFilter myFilter;
final
MyFilter2 myFilter2;
public MyFilterConfig(MyFilter myFilter, MyFilter2 myFilter2) {
this.myFilter = myFilter;
this.myFilter2 = myFilter2;
}
@Bean
public FilterRegistrationBean<MyFilter> filterFilterRegistrationBean() {
FilterRegistrationBean<MyFilter> filterRegistrationBean = new FilterRegistrationBean<>();
filterRegistrationBean.setFilter(myFilter);
filterRegistrationBean.setOrder(2);
filterRegistrationBean.setUrlPatterns(new ArrayList<>(Arrays.asList("/testFilterController", "/testFilterController1")));
return filterRegistrationBean;
}
@Bean
public FilterRegistrationBean<MyFilter2> filterFilter2RegistrationBean() {
FilterRegistrationBean<MyFilter2> filterRegistrationBean = new FilterRegistrationBean<>();
filterRegistrationBean.setFilter(myFilter2);
filterRegistrationBean.setOrder(1);
filterRegistrationBean.setUrlPatterns(new ArrayList<>(Arrays.asList("/testFilterController", "/testFilterController1")));
return filterRegistrationBean;
}
}
引用:
本文部分知识点总结引用自:https://github.com/CodingDocs/springboot-guide/blob/master/docs/basis/springboot-filter.md
作者:Snailclimb