HandlerInterceptor拦截器实现

拦截器实现

1、要想有一个拦截器 必须实现HandlerInterceptor 接口

里面有三个方法:

  1. preHandle(目标方法执行之前)
  2. postHandle(目标方法执行完成以后)
  3. afterCompletion(页面渲染以后)
/**
 * 登录检查
 * 1、配置好拦截器要拦截哪些请求
 * 2、把这些配置放在容器中
 */
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {

  /**
     * 目标方法执行之前
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

    String requestURI = request.getRequestURI();
    log.info("preHandle拦截的请求路径是{}",requestURI);

    //登录检查逻辑
    HttpSession session = request.getSession();

    Object loginUser = session.getAttribute("loginUser");

    if(loginUser != null){
      //放行
      return true;
    }

    //拦截住。未登录。跳转到登录页
    request.setAttribute("msg","请先登录");
    //        re.sendRedirect("/");
    request.getRequestDispatcher("/").forward(request,response);
    return false;
  }

  /**
     * 目标方法执行完成以后
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
  @Override
  public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    log.info("postHandle执行{}",modelAndView);
  }

  /**
     * 页面渲染以后
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
  @Override
  public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    log.info("afterCompletion执行异常{}",ex);
  }
}

2、这个拦截器要想有用 还必须将它放入到容器中。通过配置类WebMvcConfigurer 才有用

/**
 * 1、编写一个拦截器实现HandlerInterceptor接口
 * 2、拦截器注册到容器中(实现WebMvcConfigurer的addInterceptors)
 * 3、指定拦截规则【如果是拦截所有,静态资源也会被拦截】
 *
 * @EnableWebMvc:全面接管
 *      1、静态资源?视图解析器?欢迎页.....全部失效
 */
//@EnableWebMvc
@Configuration
public class AdminWebConfig implements WebMvcConfigurer{
  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new LoginInterceptor()) //添加自己写的拦截器
      .addPathPatterns("/**")  //所有请求都被拦截包括静态资源
      .excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**",
                           "/js/**","/aa/**"); 
  }
}

原理:

1、根据当前请求,找到HandlerExecutionChain【可以处理请求的handler以及handler的所有 拦截器】

2、先来顺序执行 所有拦截器的 preHandle方法

  • 1、如果当前拦截器prehandler返回为true。则执行下一个拦截器的preHandle
  • 2、如果当前拦截器返回为false。直接 倒序执行所有已经执行了的拦截器的 afterCompletion;

3、如果任何一个拦截器返回false。直接跳出不执行目标方法

4、所有拦截器都返回True。执行目标方法

5、倒序执行所有拦截器的postHandle方法。

6、前面的步骤有任何异常都会直接倒序触发 afterCompletion

7、页面成功渲染完成以后,也会倒序触发 afterCompletion

总结:

如果有多个拦截器,它会挨个去执行preHandle方法(也就是拦截器1、2、3),再去执行目标方法,然后倒序执行postHandle方法(也就是倒序拦截器3、2、1去执行),最终跳到页面渲染,渲染成功之后又倒序执行(拦截器3、2、1)的afterCompletion方法。

如果在拦截器2的preHandle就已经出现异常,那么已经执行成功的拦截器1就会把afterCompletion立即触发。相当于只要有异常就立即触发已经执行完的拦截器的afterCompletion方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值