微知识:过滤器和拦截器的区别?
1、来源不同
过滤器是 Servlet 规范中定义的一部分,它可以对客户端(浏览器)的请求和服务器的响应进行过滤操作。
拦截器是基于 Spring 等框架提供的一种机制,主要用于对特定的请求进行拦截和处理。
2、触发时机不同
过滤器执行顺序: 过滤器的执行顺序与它们在 web.xml 文件中或注解中的配置顺序有关,先配置的过滤器先执行。如果有多个过滤器,它们会按照顺序依次对请求进行过滤处理,然后再将请求传递给目标资源。响应时,也会按照相反的顺序依次经过各个过滤器的处理。
拦截器执行顺序: 拦截器的执行顺序与它们在 Spring 配置中的注册顺序有关,先注册的拦截器先执行。多个拦截器可以形成一个拦截器链,请求首先经过第一个拦截器的preHandle方法,如果该方法返回true,则继续向下执行,依次经过其他拦截器的preHandle方法,直到到达目标处理器。在处理器处理完请求后,会按照相反的顺序依次经过各个拦截器的postHandle和afterCompletion方法。
一个请求的执行顺序是:请求进入容器 > 进入过滤器 > 进入 Servlet > 进入拦截器 > 执行控制器(Controller)。所以过滤器和拦截器的触发时机也是不同的,过滤器会先执行,然后才会执行拦截器,最后才会进入真正的要调用的方法。
3、实现不同
过滤器:
实现了javax.servlet.Filter接口,并在doFilter方法中编写过滤逻辑。
需要在 web.xml 文件中进行配置,或者使用注解(如果容器支持)进行配置。
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter(filterName = "MyFilter", urlPatterns = "/*")
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 过滤器初始化时执行的操作
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 过滤前的操作
System.out.println("Filter: Before request processing");
filterChain.doFilter(servletRequest, servletResponse);
// 过滤后的操作
System.out.println("Filter: After request processing");
}
@Override
public void destroy() {
// 过滤器销毁时执行的操作
}
}
拦截器:
通过实现org.springframework.web.servlet.HandlerInterceptor接口来创建拦截器,并实现其中的preHandle、postHandle和afterCompletion方法。
在 Spring 配置文件中或者使用 Java 配置类进行配置。
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 在请求处理之前执行的操作
System.out.println("Interceptor: Before request processing");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 在请求处理之后,视图渲染之前执行的操作
System.out.println("Interceptor: After request processing but before view rendering");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 在整个请求完成后执行的操作,无论请求是否成功
System.out.println("Interceptor: After request completion");
}
}
4、作用范围不同
过滤器作用范围: 过滤器可以作用于所有的 Servlet 和 JSP,以及静态资源文件(如 HTML、CSS、JavaScript 文件等)。它可以对请求和响应的内容进行修改,例如对请求参数进行过滤、对响应内容进行压缩等。
拦截器作用范围: 拦截器主要作用于 Spring MVC 框架中的控制器方法。它可以对请求进行预处理和后处理,但不能直接修改请求和响应的内容。拦截器通常用于实现一些与业务逻辑相关的功能,如用户认证、权限检查等。
5、使用场景不同
过滤器使用场景:
统一字符编码设置:确保所有的请求和响应都使用统一的字符编码,避免出现乱码问题。
日志记录:记录请求的详细信息,如请求 URL、请求参数、响应状态码等,以便进行系统监控和故障排查。
权限验证:对请求进行权限验证,例如检查用户是否具有访问特定资源的权限。如果用户没有权限,则可以直接返回错误响应,而无需将请求传递给目标资源。
数据压缩:对响应内容进行压缩,减少网络传输的数据量,提高系统性能。
拦截器使用场景:
用户登录验证:在用户请求到达控制器方法之前,检查用户是否已经登录。如果用户未登录,则可以重定向到登录页面或者返回错误响应。
性能监控:记录请求的处理时间,以便进行系统性能分析和优化。
事务管理:在控制器方法执行前后开启和关闭事务,确保数据库操作的原子性和一致性。
日志记录:记录控制器方法的执行情况,如方法名称、参数值、返回值等,以便进行业务逻辑的监控和分析。
谦学于心,谷纳万物,静思致远,共筑收获之旅!
原文地址: https://www.emanjusaka.top/2024/09/filter-interceptor-difference
微信公众号:emanjusaka的编程栈