二者区别:
1. 实现原理不同
过滤器和拦截器 底层实现方式不相同,过滤器是基于函数回调的,拦截器则是基于Java的反射机制(动态代理)实现的。
2. 使用范围不同
过滤器实现的是 javax.servlet.Filter 接口,而这个接口是在Servlet规范中定义的,也就是说过滤器Filter 的使用要依赖于Tomcat等容器,导致它只能在web程序中使用。
而拦截器是一个Spring组件,并由Spring容器管理,并不依赖Tomcat等容器,是可以单独使用的。不仅能应用在web程序中,也可以用于Application、Swing等程序中。
3. 触发时机不同
过滤器 和 拦截器的触发时机不同。
如上图所示,过滤器Filter是在请求进入容器后,但在进入servlet之前进行预处理,请求结束是在servlet处理完以后。
拦截器 Interceptor 是在请求进入servlet后,在进入Controller之前进行预处理的,Controller 中渲染了对应的视图之后请求结束。
4. 拦截的请求范围不同
Filter对所有访问进行增强,Interceptor仅针对SpringMVC的访问进行增强。
具体说明:
在 Java Web 开发中,拦截器(Interceptor)和过滤器(Filter)是两种常用的机制,用于拦截和处理 HTTP 请求和响应。虽然它们在某些场景下可以实现类似的功能,但它们的用途、工作方式和生命周期有所不同。
拦截器(Interceptor)
主要特点:
- 工作原理:拦截器是 Spring 框架的一部分,通常用于拦截 Controller 层的请求。它通过 AOP(面向切面编程)思想,允许在方法调用前后或异常发生时执行自定义逻辑。
- 应用场景:常用于身份验证、权限检查、日志记录等操作,具体到控制器层面。
- 执行顺序:可以配置多个拦截器,并通过
preHandle
、postHandle
和afterCompletion
方法实现不同阶段的处理。
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 在请求处理之前调用(Controller方法调用之前)
System.out.println("Pre Handle method is called");
return true; // 返回 true 表示继续处理请求,返回 false 表示中止请求
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 在请求处理之后调用(Controller方法调用之后)
System.out.println("Post Handle method is called");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 在整个请求完成之后调用(通常用于资源清理)
System.out.println("Request and Response is completed");
}
}
配置拦截器:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor())
.addPathPatterns("/api/**") // 拦截所有 /api/** 路径的请求
.excludePathPatterns("/api/login"); // 排除特定路径
}
}
过滤器(Filter)
主要特点:
- 工作原理:过滤器是 Servlet 规范的一部分,作用于 Servlet 容器中,通常用于在请求到达 Servlet 之前和响应返回客户端之前进行预处理或后处理。
- 应用场景:常用于通用任务,如日志记录、身份验证、字符编码设置、跨域处理、请求和响应的修改等。
- 执行顺序:可以通过
doFilter
方法对请求和响应进行处理,多个过滤器按照配置的顺序依次执行。
示例:
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 过滤器初始化
System.out.println("Filter initialized");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 在请求处理前执行
System.out.println("Request is being filtered");
// 继续执行后续过滤器或目标资源(如Servlet)
chain.doFilter(request, response);
// 在响应处理后执行
System.out.println("Response is being filtered");
}
@Override
public void destroy() {
// 过滤器销毁
System.out.println("Filter destroyed");
}
}
配置过滤器:
- 通过
web.xml
配置:
<filter>
<filter-name>MyFilter</filter-name>
<filter-class>com.example.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/api/*</url-pattern>
</filter-mapping>
- 通过 Spring Boot 配置:
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<MyFilter> loggingFilter() {
FilterRegistrationBean<MyFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new MyFilter());
registrationBean.addUrlPatterns("/api/*"); // 过滤 /api/* 路径的请求
return registrationBean;
}
}
拦截器和过滤器的区别
-
作用范围:
- 拦截器:作用于 Spring MVC 的控制器层面,能够访问控制器处理的方法和返回的模型数据。
- 过滤器:作用于整个 Servlet 容器,可以处理所有进入的请求(包括静态资源),在请求达到控制器之前进行拦截。
-
生命周期:
- 拦截器:由 Spring 容器管理,通常在请求进入 Controller 之前、之后和整个请求完成之后执行。
- 过滤器:由 Servlet 容器管理,生命周期与应用程序一起开始和结束,在请求到达 Servlet 之前和响应返回客户端之前执行。
-
使用场景:
- 拦截器:更适合用于权限验证、业务逻辑预处理、请求日志记录等与业务相关的拦截操作。
- 过滤器:更适合用于请求和响应的全局处理,如日志记录、请求编码设置、跨域处理等。
-
执行顺序:
- 拦截器:多个拦截器之间的执行顺序可以通过配置来控制,并且可以在请求前后分别执行。
- 过滤器:多个过滤器之间按照配置的顺序依次执行。
通过理解这两者的差异,可以更好地选择和应用这两种机制来满足项目的具体需求。