在Spring项目中,Filter和Interceptor是处理HTTP请求的两种常见机制,它们功能相似,但职责和能力不同。理解它们的区别,是写出优雅架构代码的关键。
过滤器(Filter):属于 Servlet 规范,是任何Java Web项目都能用的标准组件。它在请求进入 Servlet容器(如Tomcat) 后,但还未到达Spring MVC的DispatcherServlet之前就起作用。
拦截器(Interceptor):属于 Spring MVC 框架的组件。它在请求经过DispatcherServlet之后,进入具体的Controller方法之前(以及之后)发挥作用。
这是理解它们的关键。一个HTTP请求的处理流程如下:
HTTP Request → Tomcat → Filter → DispatcherServlet → Interceptor → Controller
响应则反过来:
Controller → Interceptor(postHandle) → DispatcherServlet → Filter → HTTP Response
简单对比表:
| 特性 | 过滤器 (Filter) | 拦截器 (Interceptor) |
|---|---|---|
| 所属规范 | Servlet API | Spring MVC |
| 依赖关系 | 不依赖Spring,是Web服务器的一部分 | 依赖Spring容器 |
| 作用范围 | 对所有请求生效(包括静态资源) | 只对Spring MVC管理的请求生效 |
| 获取Bean | 不能直接注入Spring Bean | 可以直接使用@Autowired注入 |
| 控制粒度 | 粗粒度,基于请求/响应 | 细粒度,可获取处理请求的Handler、ModelAndView等 |
1. 自定义过滤器
java// 使用 @WebFilter 注解,或在 Configuration 中使用 FilterRegistrationBean
@Component
public class LogFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 1. 在Controller之前执行
System.out.println("Filter: 请求进入 - " + ((HttpServletRequest) request).getRequestURI());
long startTime = System.currentTimeMillis();
// 放行请求到下一个过滤器或DispatcherServlet
chain.doFilter(request, response);
// 2. 在返回响应给客户端之前执行
long duration = System.currentTimeMillis() - startTime;
System.out.println("Filter: 响应返回,耗时 " + duration + "ms");
}
}
2. 自定义拦截器
java@Component
public class AuthInterceptor implements HandlerInterceptor {
// 可以正常注入Spring Bean
@Autowired
private UserService userService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// Controller方法执行前调用
String token = request.getHeader("Authorization");
if (!userService.isValidToken(token)) {
response.sendError(401, "未授权");
return false; // 中断流程,不执行Controller
}
System.out.println("Interceptor: 权限校验通过");
return true; // 放行,继续执行Controller
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// Controller方法执行后,但视图渲染前调用
System.out.println("Interceptor: Controller执行完毕");
}
}
注册拦截器:
java@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private AuthInterceptor authInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authInterceptor)
.addPathPatterns("/api/**") // 只拦截/api开头的请求
.excludePathPatterns("/api/login"); // 排除登录接口
}
}
一句话总结:Filter是Web容器的保安,Interceptor是Spring MVC的秘书。
本文作者:zjx171
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!