6.拦截器

1、HandlerInterceptor 接口

第一个方法:preHandle() 预先处理器:在我们的目标方法处理之前,进行处理

第二个方法:postHandle() 目标方法执行完之后,还没到达页面之前执行,我们有可能会在页面上再放一些数据,

 第三个方法afterCompletion():页面渲染完之后,我们可以用这个方法做一些清理工作

现在我们可以写一个拦截器用于我们页面的登录检查功能

1.我们想要定制化配置,首先写一个配置类 AdminConfig 让它实现WebMvcConfig接口

2.重写里面的addInterceptors(InterceptorRegistry registry)方法

3.这个方法需要添加一个拦截器 registry.addInterceptor(new LoginInterceptor())

4.我们需要自定义一个拦截器 LoginInterceptor

5.然后写他的拦截逻辑


@Configuration
public class AdminConfig implements WebMvcConfigurer {

    @Bean
    public WebMvcConfigurer webMvcConfigurer(){
        return new WebMvcConfigurer() {
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                registry.addInterceptor(new LoginInterceptor())
                        .addPathPatterns("/**")//拦截所有请求,包括静态资源
                        //这边我们可以配置静态资源路径,但是这种方法在这里很麻烦。放行指定路径
                        .excludePathPatterns("/","/login","/css/**","/js/**","/fonts/**","/images/**");
            }
        };
    }
}


=============================================================================

 * @create 2022-08-16 9:44
 * 登陆检查
 * 我们登录之后,访问的每一个请求都应该是登录之后才可以访问的
 * 我们开始写的只做了index页面的检查,如果每一个页面都这样写就会显得代码冗余,还特别麻烦
 * 所以我们可以使用拦截器
 */
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
    //目标方法之前
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestURI = request.getRequestURI();
        log.info("拦截的请求路径是:" + requestURI);
        HttpSession session = request.getSession();
        Object loginUser = session.getAttribute("loginUser");
        if(loginUser != null){
            //放行
            return true;
        }
        //拦截住,说明没登录,让它跳转到登录界面,并提示请先登录
        request.setAttribute("msg","请先登录");
        request.getRequestDispatcher("/").forward(request,response);
        return false;

    }
    //目标方法之后
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }
    //页面渲染之后
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

2. 拦截器原理

1.根据请求获得 获得HandlerExecutionChain【可以处理请求的handler以及handler的所有的拦截器 】

2.找到这个handler的适配器,用来执行目标方法的

HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

3.在执行目标方法之前,先执行我们的拦截器的prehandle()方法:

1.先来顺序执行所有的拦截器方法 【prehandle()方法】

  1. 如果这个当前拦截器的preHandle()方法执行成功,返回的为true,就执行下一个拦截器的preHandle()
  2. 如果返回的是false,会直接触发triggerAfterCompletion()方法,这个方法,他先会记录下当前拦截器的索引,然后倒序执行已经执行了的afterCompletion()方法。

2.接着执行下一个拦截器,直到所有的拦截器执行完,中间如果有任何一个拦截器返回false,直接跳出不执行目标方法。

3.只有所有拦截器全返回true,执行目标方法

4.执行完目标方法之后,调用applyPostHandle(),倒序执行postHandle()方法

mappedHandler.applyPostHandle(processedRequest, response, mv);

 

5.前面的步骤有任何异常,都会直接出发triggerAfterCompletion()调用afterCompletion()

6.如果一切正常来到页面渲染逻辑

7.页面成功渲染完成以后,也会倒序出发afterCompletion()

if (!mappedHandler.applyPreHandle(processedRequest, response)) {
					return;
				}

applyPreHandle()

	boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
		for (int i = 0; i < this.interceptorList.size(); i++) {
            //遍历我们的拦截器
			HandlerInterceptor interceptor = this.interceptorList.get(i);
            //执行拦截器的preHandle方法
            //如果第一个拦截器调用完返回的是false,表示已经拦截了,接着会调用
            //triggerAfterCompletion(request, response, null)这个方法
			if (!interceptor.preHandle(request, response, this.handler)) {
                //这个方法,会倒序执行,每一个拦截器的afterCompletion()
				triggerAfterCompletion(request, response, null);
				return false;
			}
			this.interceptorIndex = i;
		}
		return true;
	}


======
    void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) {
		for (int i = this.interceptorIndex; i >= 0; i--) {
			HandlerInterceptor interceptor = this.interceptorList.get(i);
			try {
				interceptor.afterCompletion(request, response, this.handler, ex);
			}
			catch (Throwable ex2) {
				logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
			}
		}
	}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值