Cả hai chặn request trước controller, nhưng ở tầng khác nhau.
| Filter (Servlet) | HandlerInterceptor (Spring MVC) | |
|---|---|---|
| Tầng | Servlet container (trước DispatcherServlet) | Bên trong DispatcherServlet |
| Biết controller xử lý? | ❌ Chưa | ✅ Có (handler argument) |
| Truy cập Spring context | Hạn chế | ✅ Đầy đủ (là Spring bean) |
| Sửa request/response body | ✅ (wrap stream) | ❌ Khó |
| Use case | CORS, gzip, security (Spring Security là filter), logging thô | Auth theo handler, đo thời gian xử lý, set attribute cho view |
Cách viết:
- Filter: extend OncePerRequestFilter, override doFilterInternal(req, res, chain) — nhớ gọi chain.doFilter(...) để request đi tiếp; đăng ký như @Component.
- Interceptor: implement HandlerInterceptor — preHandle trả false → chặn request, không tới controller; postHandle sau controller; afterCompletion sau cùng (kể cả khi exception). Đăng ký qua WebMvcConfigurer.addInterceptors(...).addPathPatterns("/api/**").
Chọn: xử lý sớm/thô (security, CORS, nén, sửa body) → Filter; cần biết handler nào xử lý hoặc dùng Spring bean → Interceptor.