在构建Web应用时,我们经常需要在请求进入Controller之前或响应返回客户端之前进行一系列的预处理或后处理操作。比如记录请求日志、进行权限校验、实现跨域请求处理等。此时,Filter(过滤器)就成了我们常用的技术手段之一。
Spring Boot对Servlet规范提供了良好的支持,其中也包括对Filter的自动注册和自定义配置。在本文中,我们将深入讲解Spring Boot中Filter的工作机制、注册方式、执行顺序及其在实际开发中的典型应用场景。
一、什么是Filter?
Filter是Java Servlet规范中的组件之一,它位于Servlet容器中请求链的中间位置,主要用于对进入Servlet的请求或从Servlet返回的响应进行过滤处理。
Filter的典型用途包括:
-
请求日志记录
-
权限验证
-
XSS过滤
-
跨域支持(CORS)
-
内容压缩(如Gzip)
二、Spring Boot中使用Filter的两种方式
1. 通过@WebFilter
注解 + @ServletComponentScan
扫描
这是直接遵循Servlet规范的方式,适合较简单的应用场景。
java
@WebFilter(filterName = "logFilter", urlPatterns = "/*") public class LogFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("请求进入LogFilter..."); chain.doFilter(request, response); System.out.println("响应离开LogFilter..."); } }
在启动类上加上:
java
@SpringBootApplication @ServletComponentScan public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
2. 通过@Bean方式注册Filter(推荐)
这种方式更加灵活,也更符合Spring Boot的编程风格。
java
复制编辑
@Configuration public class FilterConfig { @Bean public FilterRegistrationBean<LogFilter> logFilter() { FilterRegistrationBean<LogFilter> registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new LogFilter()); registrationBean.addUrlPatterns("/*"); registrationBean.setOrder(1); // 控制执行顺序 return registrationBean; } }
三、Filter的执行顺序控制
在实际项目中,我们可能会配置多个过滤器,例如日志记录、权限控制、跨域处理等。这时候就需要明确各个Filter的执行顺序。
使用FilterRegistrationBean
时,可以通过setOrder(int order)
设置执行顺序,数字越小,优先级越高。
四、Filter与Interceptor的区别
特性 | Filter | Interceptor |
---|---|---|
所属规范 | Java EE Servlet规范 | Spring MVC框架 |
作用范围 | Servlet请求(包括静态资源) | Controller请求 |
使用场景 | 安全验证、日志记录、XSS过滤等 | 登录检查、权限控制、数据封装等 |
生命周期控制 | 由Servlet容器管理 | 由Spring容器管理 |
配置方式 | 注解或Bean注册 | 实现HandlerInterceptor并注册 |
五、常见使用场景实战
1. 请求日志打印
java
public class RequestLogFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; System.out.println("请求路径:" + httpRequest.getRequestURI()); chain.doFilter(request, response); } }
2. 简单的权限校验
java
public class AuthFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; String token = httpRequest.getHeader("Authorization"); if (token == null || !token.equals("valid-token")) { HttpServletResponse httpResponse = (HttpServletResponse) response; httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "权限不足"); return; } chain.doFilter(request, response); } }
六、结语
Filter是构建Web应用不可或缺的工具,掌握其工作机制和注册方式,能够让你在项目开发中更加得心应手。相比于Spring MVC中的Interceptor,Filter 23ph.zghaa.name 更接近底层,控制更精细,适用于一些底层逻辑处理。
建议在项目初期就规划好Filter的使用结构,以避免后期混乱,同时注意合理划分职责和顺序,避免性能问题和请求冲突。