维度 | 过滤器(Filter) | 拦截器(Interceptor) |
---|---|---|
规范层级 | Servlet规范(J2EE标准) | Spring MVC框架机制 |
作用范围 | 所有请求(包括静态资源) | 只处理Controller请求 |
依赖关系 | 不依赖Spring容器 | 完全集成Spring IOC容器 |
执行顺序 | 最先执行(在DispatcherServlet之前) | 在DispatcherServlet之后执行 |
异常处理 | 无法直接使用Spring的异常处理机制 | 可以通过@ControllerAdvice统一处理 |
HTTP Request
↓
Filter Chain(doFilter)
↓
DispatcherServlet
↓
Interceptor.preHandle
↓
Controller Method
↓
Interceptor.postHandle
↓
View Rendering(如有)
↓
Interceptor.afterCompletion
↓
Filter Chain(返回响应)
@Component
public class LogFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
long startTime = System.currentTimeMillis();
HttpServletRequest req = (HttpServletRequest) request;
// 前置处理
System.out.println("Request URI: " + req.getRequestURI());
chain.doFilter(request, response); // 放行请求
// 后置处理
long duration = System.currentTimeMillis() - startTime;
System.out.println("Request completed in " + duration + "ms");
}
}
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<LogFilter> loggingFilter() {
FilterRegistrationBean<LogFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(new LogFilter());
registration.addUrlPatterns("/api/*");
registration.setOrder(Ordered.HIGHEST_PRECEDENCE); // 设置优先级
return registration;
}
}
典型应用场景:
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
String token = request.getHeader("Authorization");
if (!validateToken(token)) {
response.sendError(401, "Invalid token");
return false; // 中断请求
}
return true;
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception {
// Controller方法执行后,视图渲染前
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) throws Exception {
// 请求完全结束后(包括视图渲染)
}
}
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private AuthInterceptor authInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/login", "/public/**");
}
}
典型应用场景:
配置多个过滤器和拦截器时的执行顺序:
Filter1 → Filter2 → Interceptor.preHandle
→ Controller
→ Interceptor.postHandle
→ Interceptor.afterCompletion
→ Filter2 → Filter1
// 在过滤器中处理异常
public void doFilter(...) {
try {
chain.doFilter(request, response);
} catch (Exception e) {
response.sendError(500, "Server Error");
}
}
// 在拦截器中处理异常
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<?> handleException(Exception e) {
return ResponseEntity.internalServerError().body("Error occurred");
}
}
// 拦截器需实现AsyncHandlerInterceptor
@Override
public void afterConcurrentHandlingStarted(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
// 异步请求的特殊处理
}
是否需要处理静态资源?
├─ 是 → 必须使用Filter
└─ 否 →
是否需要访问Spring Bean?
├─ 是 → 选择Interceptor
└─ 否 →
是否需要最早处理请求?
├─ 是 → 选择Filter
└─ 否 → 根据业务复杂度选择
// 拦截器实现
public class MetricsInterceptor implements HandlerInterceptor {
private static final ThreadLocal<Long> startTime = new ThreadLocal<>();
@Override
public boolean preHandle(...) {
startTime.set(System.currentTimeMillis());
return true;
}
@Override
public void afterCompletion(...) {
long duration = System.currentTimeMillis() - startTime.get();
metricsService.recordRequestTime(request.getRequestURI(), duration);
startTime.remove();
}
}
public class ReplayAttackFilter implements Filter {
private Cache<String, Boolean> requestCache =
Caffeine.newBuilder().expireAfterWrite(5, TimeUnit.MINUTES).build();
@Override
public void doFilter(...) {
String nonce = request.getHeader("X-Nonce");
if (requestCache.getIfPresent(nonce) != null) {
response.sendError(400, "Duplicate request");
return;
}
requestCache.put(nonce, true);
chain.doFilter(request, response);
}
}
通过合理运用过滤器和拦截器,开发者可以构建出高可维护性的Web应用架构。建议结合APM工具(如SkyWalking)监控两者的执行效率,持续优化系统性能。