过滤器和拦截器

86 阅读4分钟

过滤器介绍

  1. 过滤器是基于AOP实现的用于对请求进行前置和后置处理的一种配置工具
  2. 过滤器是基于函数回调实现的
  3. 过滤器只能在web项目中使用,依赖servlet容易实现
  4. 过滤器几乎可以对任意请求进行过滤

过滤器的作用和分类

  • 作用:
  1. 在HttpServletRequest 到达Servlet 之前,拦截客户的HttpServletRequest 。据需要检查HttpServletRequest ,也可以修改HttpServletRequest 头和数据
  2. 在HttpServletResponse 到达客户端之前,拦截HttpServletResponse 。根据需要检查HttpServletResponse ,可以修改HttpServletResponse 头和数据
  3. 可以简单的理解,就是拦截HttpServletRequest和HttpServletResponse进行处理,合适的就放行,不合适的就拦截
  • 分类:
  1. 用户授权的Filter:Filter负责检查用户请求,根据请求过滤用户非法请求
  2. 日志Filter:详细记录某些特殊的用户请求
  3. 负责解码的Filter:包括对非标准编码的请求解码
  4. 能改变XML 内容的XSLTFilter等

过滤器的实现

import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@Component
@WebFilter(urlPatterns = "/*")
public class TestFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("过滤器:执行 init 方法。");
    }
    @Override
    public void doFilter(ServletRequest servletRequest,
                         ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        System.out.println("过滤器:开始执行 doFilter 方法。");
        // 请求放行
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("过滤器:结束执行 doFilter 方法。");
    }
    @Override
    public void destroy() {
        System.out.println("过滤器:执行 destroy 方法。");
    }
}
  1. 过滤器必须通过@Component交给Spring容器进行管理
  2. @WebFilter是用来设置哪些请求需要被拦截
  3. 要实现Filter接口,Filter接口中有三个方法需要集成,分别是init、doFilter和destory
  • init():整个程序运行过程中只会调用一次,是实现对Filter对象的初始化,不用过分关注这个方法
  • doFilter():过滤器的核心方法,过滤器核心功能在这个方法中实现,其中 FilterChain 参数是用来调用下一个过滤器或执行下一个流程
  • destroy():用于Filter销毁前完成相关的资源回收工作

拦截器介绍

拦截器实现

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class TestInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截器:执行 preHandle 方法。");
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("拦截器:执行 postHandle 方法。");
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("拦截器:执行 afterCompletion 方法。");
    }
}
  1. 可以看到拦截器和过滤器的实现非常的像,都实现了一个接口,也同样的都有三个方法要实现
  2. 同样的拦截器也必须要通过@Component注解交给Spring容器管理
  • preHandle():在请求方法执行前调用,比如操作数据前必须验证用户的登录状态,验证通过返回true,继续执行数据操作业务,否则不执行。所以说实际上拦截器的切点是controller层中的方法
  • postHandle():同样是拦截器的核心方法,完成第一个方法的验证之后,才会进到这一步,在请求之后渲染之前执行。
  • afterHandle():会在整个请求结束之后再执行,也就是在 DispatcherServlet 渲染了对应的视图之后再执行

拦截器需要进行配置,配置如下

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class AppConfig implements WebMvcConfigurer {

    // 注入拦截器
    @Autowired
    private TestInterceptor testInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(testInterceptor) // 添加拦截器
                .addPathPatterns("/*"); // 拦截所有地址
    }
}

过滤器和拦截器的区别

  1. 过滤器来自于Servlet相关的包,拦截器来自Spring框架的包

  2. 由上面一点就可以知道拦截器适用范围更加广,在支持Spring的项目中都可以应用,过滤器只适用于web项目

  3. 过滤器是基于回调函数实现的,在doFilter方法中需要调用doFilter进行下一个过滤器或流程的实现,拦截器则是基于反射实现的,也就是动态代理 image.png

  4. 执行的时间不同:执行顺序进入Tomcat容器->过滤器->Servlet->拦截器->控制器 image.png

  5. 实现功能不同

  • 因为拦截器更接近业务系统,所以拦截器主要用来实现项目中的业务判断的,比如:登录判断、权限判断、日志记录等业务。 而过滤器通常是用来实现通用功能过滤的,比如:敏感词过滤、字符集编码设置、响应数据压缩等功能