框架给我们的开发带来很多便利的地方,而许多从前学习到的一些知识的使用,在框架中会稍有不同,该文章主要对过滤器和拦截器在框架中的使用进行描述,并分析过滤器、拦截器和AOP的关系及区别

过滤器

过滤器的作用主要是对路径匹配的请求进行拦截,然后对请求进行相应处理后,再将请求放行去执行原来的处理逻辑。

springmvc 多个过滤器 springmvc的过滤器_springmvc 多个过滤器

当有多个过滤器时,会形成一个过滤器链,会逐一执行,只有在请求路径匹配时,才会被过滤器拦截

使用

创建一个类,实现Filter接口,并重写doFilter()方法

@Slf4j
public class TimeFilter implements Filter {
    private SimpleDateFormat simpleDateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:S");
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        log.info("TimeFilter拦截的时间:{}",simpleDateFormat.format(new Date(System.currentTimeMillis())));
        chain.doFilter(request, response);
        log.info("执行完请求处理逻辑后,回到TimeFilter的时间:{}",simpleDateFormat.format(new Date(System.currentTimeMillis())));
    }
}

创建配置类,利用方法创建过滤器并放入容器中

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Bean
    public FilterRegistrationBean TimeFilter(){
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        TimeFilter timeFilter = new TimeFilter();
        filterRegistrationBean.setFilter(timeFilter);
        // 添加拦截路径
        filterRegistrationBean.addUrlPatterns("/filter/*");
        Set<String> path = new HashSet<>();
        // 多路径情况
        // path.add("/filter/test1");
        // path.add("/filter/test2");
        // filterRegistrationBean.setUrlPatterns(path);
        // 设置过滤器的执行顺序
        filterRegistrationBean.setOrder(1);
        return filterRegistrationBean;
    }
}
测试

请求接口并查看日志信息

springmvc 多个过滤器 springmvc的过滤器_springmvc 多个过滤器_02

在日志信息可以看到,请求成功被过滤器拦截


拦截器

拦截器也是根据请求路径来进行拦截的,拦截器类似于Aop,都是使用代理模式实现的,它可对你所需访问的接口方法的执行前后进行操作。在框架中,可以通过实现HandlerInterceptor接口来创建拦截器,需重写preHandle()、postHandle()、afterCompletion()三个方法。

springmvc 多个过滤器 springmvc的过滤器_spring_03

使用

创建一个类,实现HandlerInterceptor接口并重写preHandle()、postHandle()、afterCompletion()方法

@Slf4j
@Component
public class TimeInterceptor implements HandlerInterceptor {
    private SimpleDateFormat simpleDateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:S");
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("调用TimeInterceptor中的preHandle()方法的时间:{}",simpleDateFormat.format(new Date(System.currentTimeMillis())));
        // 只有返回值为true时,才能够继续执行postHandle()、afterCompletion()方法,若是false表示请求结束,将会不再执行
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("调用TimeInterceptor中的postHandle()方法的时间:{}",simpleDateFormat.format(new Date(System.currentTimeMillis())));
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("调用TimeInterceptor中的afterCompletion()方法的时间:{}",simpleDateFormat.format(new Date(System.currentTimeMillis())));
    }
}

在配置类中,把拦截器添加到容器中,并设置拦截路径

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private TimeInterceptor timeInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(timeInterceptor).addPathPatterns("/interceptor/*");
//        多路径配置
//        List<String> path = new ArrayList<>();
//        path.add("/interceptor/test1");
//        path.add("/interceptor/test2");
//        registry.addInterceptor(timeInterceptor).addPathPatterns(path);
    }
}
测试

请求接口并查看日志信息

springmvc 多个过滤器 springmvc的过滤器_springmvc 多个过滤器_04

在日志中可以看到,拦截器已经成功拦截到了请求,并执行了三个方法


过滤器、拦截器、Aop

执行顺序

当过滤器、拦截器、Aop都用于一个请求路径的接口方法时,执行顺序为 过滤器-》拦截器-》AOP

springmvc 多个过滤器 springmvc的过滤器_aop_05

作用
过滤器的主要作用
  • 用户访问权限处理
  • 设置字符集乱码处理
  • 过滤敏感词汇、压缩响应信息
拦截器的主要作用
  • 只能拦截请求,可以访问上下文等对象,功能强大,一个请求可多次拦截。
  • 用户访问权限处理
  • 登记日志
AOP的主要作用
  • 日志记录
  • 性能统计
  • 安全控制
  • 事务处理
  • 异常处理
  • 只能应用于由 Spring 容器管理的 bean

一般情况下,数据被过滤拦截的时机越早对服务的性能影响越小,在编写相对比较公用的代码时,优先考虑过滤器,然后是拦截器,最后是AOP

区别
  • 过滤器与拦截器的拦截是通过匹配请求路径实现的,而AOP(面向切面)拦截可以通过切点切向包、类、方法名、参数等
  • Spring AOP和拦截器一样,都是AOP的实现方式的一种,均使用代理模式实现
  • Aop能够对包、类、方法名、参数等拦截,相对于拦截其而言,更加灵活,Aop可以针对具体的代码,去实现更加复杂的业务逻辑
  • 拦截器只对action负责,作用层面一般位于Controller层,Spring AOP主要是拦截对Spring管理的Bean的访问,一般作用与Service层