HandlerInterceptorAdapter之自定义拦截器

一、拦截器执行顺序

 二、应用场景

1、日志记录,可以记录请求信息的日志,以便进行信息监控、信息统计等。
2、权限检查:如登录检测,进入处理器检测是否登陆,如果没有直接返回到登陆页面。
3、性能监控:典型的是慢日志。

4、自定义注解:实现自定义注解的功能。

 三、HandlerInterceptorAdapter与HandlerInterceptor

HandlerInterceptor是一个接口,需要实现


public interface HandlerInterceptor {
 
   /**
     * 预处理回调方法,实现处理器的预处理(如检查登陆),第三个参数为响应的处理器,自定义Controller
     * 返回值:true表示继续流程(如调用下一个拦截器或处理器);false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;
   */
    boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception;
 
   /**
     * 后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。
   */
    void postHandle(
            HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
            throws Exception;
 
   /**
    * 整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中
   */
    void afterCompletion(
            HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception;
 
}

HandlerInterceptorAdapter是抽象类没有抽象方法,按需引入覆写就行

public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor {

   /**This implementation always returns {@code true}.*/
   @Override
   public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
         throws Exception {

      return true;
   }

   /** This implementation is empty.*/
   @Override
   public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
         @Nullable ModelAndView modelAndView) throws Exception {
   }

   /**This implementation is empty.*/
   @Override
   public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
         @Nullable Exception ex) throws Exception {
   }

   /**This implementation is empty.*/
   @Override
   public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response,
         Object handler) throws Exception {
   }

}

四、自定义拦截器与WebMvcConfigurer

WebMvcConfigurer是一个接口,旧的版本是继承WebMvcConfigurerAdapter

常用方法

/** 拦截器配置 */
void addInterceptors(InterceptorRegistry var1);

/* 视图跳转控制器 */
void addViewControllers(ViewControllerRegistry registry);

/** 静态资源处理*/
void addResourceHandlers(ResourceHandlerRegistry registry);

/** 默认静态资源处理器 */
void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer);

/** 这里配置视图解析器*/
void configureViewResolvers(ViewResolverRegistry registry);

/** 配置内容裁决的一些选项*/
void configureContentNegotiation(ContentNegotiationConfigurer configurer);

/** 解决跨域问题 */
public void addCorsMappings(CorsRegistry registry) ;

 这里重点讲下addInterceptors(InterceptorRegistry var1)方法:注册拦截器

1、addInterceptor:需要一个实现HandlerInterceptor接口的拦截器实例

2、addPathPatterns:用于设置拦截器的过滤路径规则;addPathPatterns("/**")对所有请求都拦截

3、excludePathPatterns:用于设置不需要拦截的过滤规则

4、拦截器主要用途:进行用户登录状态的拦截,日志的拦截等。

@Configuration
public class WebConfiguration implements WebMvcConfigurer {

    // 注册拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        ArrayList<String> commonPathPatterns = getExcludeCommonPathPatterns();
        registry.addInterceptor(getTestInterceptor1()).addPathPatterns("/**").excludePathPatterns(commonPathPatterns.toArray(new String[]{}));
        registry.addInterceptor(getTestInterceptor2()).addPathPatterns("/**").excludePathPatterns(commonPathPatterns.toArray(new String[]{}));
    }

    @Bean
    TestInterceptor1 getTestInterceptor1() {
        return new TestInterceptor1();
    }

    @Bean
    TestInterceptor2 getTestInterceptor2() {
        return new TestInterceptor2();
    }
}

五、那底层是什么呢

基于责任链模式与JDK动态代理。

六、总结

  1. 拦截器执行顺序是按照WebMvcConfigurer配置中定义的顺序而定的。
  2. 会先按照顺序执行所有拦截器的preHandle方法,一直遇到return false为止,比如第二个preHandle方法是return false,则第三个以及以后所有拦截器都不会执行。若都是return true,则按顺序加载完preHandle方法。
  3. 然后执行主方法(自己的controller接口),若中间抛出异常,则跟return false效果一致,不会继续执行postHandle,只会倒序执行afterCompletion方法。
  4. 在主方法执行完业务逻辑(页面还未渲染数据)时,按倒序执行postHandle方法。若第三个拦截器的preHandle方法return false,则会执行第二个和第一个的postHandle方法和afterCompletion(postHandle都执行完才会执行这个,也就是页面渲染完数据后,执行after进行清理工作)方法。(postHandle和afterCompletion都是倒序执行)

如果对你有帮助帮忙点个赞哈

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卡布奇诺-海晨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值