一、核心概念对比
维度 | 过滤器(Filter) | 拦截器(Interceptor) |
---|---|---|
规范层级 | Servlet 规范(J2EE 标准) | Spring MVC 框架机制 |
作用范围 | 所有请求 | 仅处理 Controller 层请求 |
执行时机 | 在 DispatcherServlet 之前执行 | 在 DispatcherServlet 之后、Controller 方法调用前/后执行 |
依赖关系 | 不依赖 Spring 容器 | 完全集成 Spring IOC 容器, 可注入 Bean |
异常处理 | 无法直接使用 Spring 的 @ControllerAdvice | 可通过 @ControllerAdvice 统一处理异常 |
生命周期管理 | 由 Servlet 容器管理(init/destroy ) | 由 Spring 管理,可通过 @Autowired 获取其他 Bean |
执行流程 | 全局处理(如字符编码、日志统计) | 业务相关处理 (如权限校验、接口限流) |
二、执行流程示意图
HTTP Request
↓
Filter Chain (doFilter)
→ 全局处理(如字符编码、XSS 过滤)
↓
DispatcherServlet
↓
Interceptor.preHandle
→ 权限校验、接口限流
↓
Controller Method
↓
Interceptor.postHandle
→ 响应数据封装、日志补充
↓
View Rendering(如有)
↓
Interceptor.afterCompletion
→ 资源清理
↓
Filter Chain(返回响应)
→ 响应压缩、跨域处理
三、技术实现差异
1. Filter 的实现
- 代码示例:
@Component
@WebFilter(urlPatterns = "/*")
public class LogFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
long start = System.currentTimeMillis();
chain.doFilter(request, response); // 必须调用以传递请求
System.out.println("请求耗时:" + (System.currentTimeMillis() - start) + "ms");
}
}
- 注册方式:
- 注解:
@WebFilter + @ServletComponentScan
- 配置类:通过
FilterRegistrationBean
设置优先级
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<LogFilter> loggingFilter() {
FilterRegistrationBean<LogFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(new LogFilter());
registration.addUrlPatterns("/*");
registration.setOrder(Ordered.HIGHEST_PRECEDENCE); // 设置优先级
return registration;
}
}
2. Interceptor 的实现
- 代码示例:
@Component
public class LogInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
System.out.println("PreHandle: 请求路径=" + request.getRequestURI());
return true; // 返回 true 表示继续执行后续流程
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
System.out.println("PostHandle: 请求处理完成");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
System.out.println("AfterCompletion: 请求流程完全结束");
}
}
- 注册方式:
@Configuration
public class WebConfig implements WebMvcConfigurer {
private final LogInterceptor logInterceptor;
public WebConfig(LogInterceptor logInterceptor) {
this.logInterceptor = logInterceptor;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(logInterceptor)
.addPathPatterns("/**") // 拦截所有路径
.excludePathPatterns("/public/**"); // 排除公共路径
}
}
四、实战应用场景
1. Filter 的典型应用
- 跨域处理:
@Component
@WebFilter("/*")
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
}
- 字符编码转换:
@Component
@WebFilter("/*")
public class EncodingFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
req.setCharacterEncoding("UTF-8");
res.setCharacterEncoding("UTF-8");
chain.doFilter(req, res);
}
}
2. Interceptor 的典型应用
- 权限校验:
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
String token = request.getHeader("Authorization");
if (token == null || !isValidToken(token)) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "未授权");
return false;
}
return true;
}
private boolean isValidToken(String token) {
// 实际业务中校验 token 有效性
return true;
}
}
- 性能监控:
@Component
public class PerformanceInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
request.setAttribute("startTime", System.currentTimeMillis());
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
long duration = System.currentTimeMillis() - (Long) request.getAttribute("startTime");
System.out.println("请求耗时:" + duration + "ms");
}
}
五、注意事项与最佳实践
1. Filter 与 Interceptor 的选择
- Filter 适用于全局性、与业务无关的处理(如跨域、编码、日志)。
- Interceptor 适用于与业务逻辑相关的处理(如权限校验、参数预处理)。
2. 异常处理
- Filter:无法直接使用 Spring 的异常处理机制,需手动捕获并处理异常。
- Interceptor:可通过
@ControllerAdvice
统一处理异常。
3. 性能优化
- Filter:由于作用于所有请求,需避免在
doFilter
中执行复杂逻辑。 - Interceptor:建议在
preHandle
中尽量减少耗时操作,避免影响请求吞吐量。
4. 优先级控制
- Filter:通过
FilterRegistrationBean.setOrder()
设置优先级。 - Interceptor:通过
InterceptorRegistry.addInterceptor()
注册顺序控制执行顺序。
六、总结
特性 | Filter 适用场景 | Interceptor 适用场景 |
---|---|---|
全局处理 | ✅ 跨域、编码、日志 | ❌ 仅处理 Controller 请求 |
业务逻辑处理 | ❌ 与业务无关 | ✅ 权限校验、参数预处理 |
依赖 Spring 容器 | ❌ 不依赖 | ✅ 可注入 Bean |
异常处理 | ❌ 需手动处理 | ✅ 支持 @ControllerAdvice |
执行顺序 | ✅ 最先执行(DispatcherServlet 之前) | ✅ 在 DispatcherServlet 之后执行 |
通过合理选择 Filter 和 Interceptor,开发者可以高效实现请求处理的分层与解耦,提升系统的可维护性和扩展性。
© 版权声明
本站资源来自互联网收集,仅供用于学习和交流,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!
THE END