1. 基本实现
要注意的是Filter默认拦截所有请求,包括静态资源
而Interceptor默认只拦截Controller请求,除非在注册拦截器的时候有特殊配置(具体可以看下面配置部分)
// 过滤器实现
@Component
@Slf4j
public class CustomFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
// 前置处理
log.info("Filter 处理前");
// 调用下一个过滤器或目标资源
chain.doFilter(request, response);
// 后置处理
log.info("Filter 处理后");
}
}
// 拦截器实现
//拦截器:默认只拦截Controller的请求
//默认不会拦截到静态资源请求
//除非在WebMvcConfigurer中特别配置
@Component
@Slf4j
public class CustomInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
log.info("Interceptor 前置处理");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception {
log.info("Interceptor 后置处理");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) throws Exception {
log.info("Interceptor 完成处理");
}
}
2. 配置方式
// 过滤器配置
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<CustomFilter> customFilter() {
FilterRegistrationBean<CustomFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new CustomFilter());
registrationBean.addUrlPatterns("/*");//设置匹配路径
registrationBean.setOrder(1);//设置优先级
return registrationBean;
}
}
// 拦截器配置
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new CustomInterceptor())
//特殊处理!!!
.addPathPatterns("/**")//拦截所有请求
.excludePathPatterns("/static/**");///排除某些请求
.order(1);// 设置优先级
}
}
3. 主要区别
1. 实现原理不同
Filter: 基于 Servlet 规范,在 Servlet 容器级别
Interceptor: 基于 Spring AOP,在 Spring MVC 框架级别,访问Servlet的时候不会经过拦截器
原因:请求Servlet的时候,请求不会到达DispatherServlet(前端控制器),走的不是Spring流程,而是Tomcat请求Servlet的流程
请求处理顺序:
1. Filter
2. Servlet
3. DispatcherServlet (如果请求未被Servlet处理)
4. Interceptor
5. Controller
2. 使用范围不同
过滤器不会处理请求转发, 拦截器会处理请求转发!!!
原因:请求转发是在servlet级别中调用,不会经过过滤器,要想经过过滤器需要使用重定向!
Filter: 可以拦截所有请求,包括静态资源
这意味着:
- Filter 能够拦截所有到达服务器的请求
- 包括对 HTML、CSS、JS、图片等静态资源的请求
- 在 Servlet 容器层面工作(比如 Tomcat)
Interceptor: 只能拦截 Spring MVC 的请求
- 只能拦截被 Spring MVC 的 DispatcherServlet 处理的请求
- 默认情况下不会拦截静态资源(除非特殊配置)
- 在 Spring 框架层面工作
3. 接口调用顺序
执行顺序:
- Filter.doFilter() 前置处理
- Interceptor.preHandle()
- Controller 方法
- Interceptor.postHandle()
- Interceptor.afterCompletion()
- Filter.doFilter() 后置处理
4. 资源访问能力
Filter:
- 能够访问 ServletRequest/ServletResponse
- 不能访问 Controller 方法的参数和返回值
Interceptor:
- 能够访问 Controller 方法的参数和返回值
- 可以获取 Spring 上下文中的 Bean
5. 选择建议
使用 Filter:
- 需要处理所有请求(包括静态资源)
- 需要在 Servlet 容器级别处理
- 与 Web 容器密切相关的功能
使用 Interceptor:
- 需要访问 Controller 上下文
- 需要使用 Spring 的功能
- 只需处理 Spring MVC 的请求
两者结合:
- Filter 处理通用的请求/响应处理
- Interceptor 处理业务逻辑相关的拦截