该趟专车是开往SpringBoot自定义Filter的实战专车,我们都知道Filter可以帮助完成许多统一的业务处理功能,比如:打印web请求日志、记录web请求耗时、请求鉴权等等;还可以实现资源初始化、资源释放功能。如此可以看出Filter在web开发中的地位,该篇文章将通过多种方式来实现Filter的定义,让大家充分掌握此利器。
SpringBoot可以通过几种方式来定义Filter?
第一步:在父模块下面新建一个名为boot-example-filter的子模块
第二步:子模块添加如下依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
第三步:创建filter
第一种实现方式:使用@Component注解标注
@Component
@Order(1)
@Slf4j
public class CustomFilter1 implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
log.info("执行被@Component标注的CustomFilter1的doFilter方法");
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("执行被@Component标注的CustomFilter1的init方法");
}
@Override
public void destroy() {
log.info("执行被@Component标注的CustomFilter1的destroy方法");
}
}
第二种实现方式:使用FilterRegistrationBean进行注册
@Slf4j
public class CustomFilter2 implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
log.info("执行被CustomFilter2的doFilter方法");
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("执行CustomFilter2的init方法");
}
@Override
public void destroy() {
log.info("执行CustomFilter2的destroy方法");
}
}
@Configuration
public class WebFilterConfiguration {
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new CustomFilter2());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.setOrder(2);
return filterRegistrationBean;
}
}
第三种实现方式:使用Servlet提供的注解@WebFilter来定义Filter,该种实现方式需要在启动类上添加@ServletComponentScan注解
@Slf4j
@WebFilter(filterName = "customFilter3", urlPatterns = "/*")
@Order(3)
public class CustomFilter3 implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
log.info("执行被CustomFilter3的doFilter方法");
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("执行被CustomFilter3的init方法");
}
@Override
public void destroy() {
log.info("执行被CustomFilter3的destroy方法");
}
}
第四步:创建启动类
@SpringBootApplication
@ServletComponentScan
public class FilterApplication {
public static void main(String[] args) {
SpringApplication.run(FilterApplication.class);
}
}
第五步:启动应用,查看日志
执行CustomFilter2的init方法
执行被@Component标注的CustomFilter1的init方法
执行CustomFilter3的init方法
第六步:访问应用
执行被@Component标注的CustomFilter1的doFilter方法
执行CustomFilter2的doFilter方法
执行CustomFilter3的doFilter方法
第七步:关闭应用
执行CustomFilter2的destroy方法
执行被@Component标注的CustomFilter1的destroy方法
执行CustomFilter3的destroy方法
如上通过启动应用来执行Filter的初始化方法、发送web请求来指定Filter的doFilter方法、停止应用来执行Filter的销毁方法
在SpringBoot中可以通过三种方式来定义Filter:
第一种:实现Filter接口并使用@Compnent注解标注,此种方式只能过滤/*这种路径,不能过滤特定路径
第二种:实现Filter接口并使用FilterRegistrationBean进行注册,此种方式可以更灵活定义需要过滤的路径形式(推荐使用该方式)
第三种:实现Filter接口,使用@WebFilter标注,并且需要在启动类中添加@ServletComponentScan注解,比较麻烦