Filter 是 JavaEE 中 Servlet 规范的一个组件,位于包javax.servlet 中,它可以在 HTTP 请求到达 Servlet 之前,被一个或多个Filter处理。
Filter 工作流程如图:
Filter在生产环境中有很广泛的应用,如:修改请求和响应、防止xss攻击、包装二进制流使其可以多次读等。
Filter接口 doFilter 的方法,这个方法实现了对用户请求的过滤。具体流程如下:
显式配置 Filter ,功能强大,配置灵活。只需要把每个自定义的 Filter 声明成 Bean 交给 Spring 管理即可,还可以设置匹配的 URL 、指定 Filter 的先后顺序
MyFilter.java
/**
* 功能描述: 自定义过滤器
* @author TuYong
* @date 2022/6/13 10:26
*/
@Slf4j
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("init filter {}", filterConfig.getFilterName());
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
log.info("do filter");
HttpServletRequest request = (HttpServletRequest) servletRequest;
String requestUri = request.getRequestURI();
log.info("请求的接口为 {}", requestUri);
long startTime = System.currentTimeMillis();
filterChain.doFilter(servletRequest, servletResponse);
long endTime = System.currentTimeMillis();
log.info("该用户的请求已经处理完毕,请求花费的时间为 {}" , (endTime - startTime));
}
@Override
public void destroy() {
log.info("destroy filter");
}
}
MyFilterConfig.java
/**
* 功能描述: 过滤器配置
* @author TuYong
* @date 2022/6/13 10:29
*/
@Configuration
public class MyFilterConfig {
@Bean
public FilterRegistrationBean filterRegistration(){
// 新建过滤器注册类
FilterRegistrationBean registration = new FilterRegistrationBean<>();
// 添加自定义 过滤器
registration.setFilter(myFilter());
// 设置过滤器的URL模式
registration.addUrlPatterns("/api/*");
//设置过滤器顺序
registration.setOrder(1);
return registration;
}
@Bean
public MyFilter myFilter(){
return new MyFilter();
}
}
测试接口ApiController.java
/**
* 功能描述: 测试接口
* @author TuYong
* @date 2022/6/13 10:39
*/
@RestController
@RequestMapping("/api")
public class ApiController {
@GetMapping("/test1")
public Object test1(){
return "success";
}
}
测试结果
访问接口http://127.0.0.1:8080/api/test1后,可以看到控制台打印如下:
@WebFilter+@ServletComponentScan 注解方式支持对 Filter 匹配指定URL,但是不支持指定 Filter 的执行顺序。
@Slf4j
@WebFilter(urlPatterns = "/api/*")
public class MyFilter2 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("init filter2 {}", filterConfig.getFilterName());
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
log.info("do filter2");
}
@Override
public void destroy() {
log.info("destroy filter2");
}
}
/**
* 功能描述: Sb启动类
* @author TuYong
* @date 2022/6/13 11:19
*/
@SpringBootApplication
@ServletComponentScan("com.example.springbootfilter.filter")
public class SpringbootFilterApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootFilterApplication.class, args);
}
}
测试结果如下:
访问接口http://127.0.0.1:8080/api/test1后,可以看到控制台打印如下:
MyFilter类上加上@Component和@Order注解即可。
当有多个Filter时,这里的@Order(1)注解会指定执行顺序,数字越小,越优先执行,如果只写@Order,默认顺序值是Integer.MAX_VALUE。
@Component + @Order 注解方式配置简单,支持自定义 Filter 顺序。缺点是只能拦截所有URL,不能通过配置去拦截指定的 URL。
@Slf4j
@Component
@Order(1)
public class MyFilter3 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("init filter3 {}", filterConfig.getFilterName());
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
log.info("do filter3");
}
@Override
public void destroy() {
log.info("destroy filter3");
}
}
留言与评论(共有 0 条评论) “” |