SpringMVC 拦截器

SpringMVC 拦截器

上篇笔记了记录了 SpringBoot 如何注入Servlet 三大组件,其中包括 Filter 的使用:SpringBoot 注册Servlet,Filter,Listener 这篇笔记要说的拦截器和 Filter 的作用其实差不多。
首先来说用法,要实现一个拦截器需要以下几步:

1、编写一个类实现 HandlerInterceptor 接口

public class MyInterceptor implements HandlerInterceptor {
    /**
     * 目标方法执行之前执行
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession();
        Object loginUser = session.getAttribute("loginUser");
        if (loginUser != null) {
            return true
        }
        request.setAttribute("msg", "请先登录");
        // 转发到登录页
        request.getRequestDispatcher("/login").forward(request, response);
        return false;
    }
    /**
     * 目标方法执行之后执行
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }
    /**
     * 页面渲染之后执行
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }
}

2、把拦截器注入到容器中

@Configuration
// SpringBoot中所有定制实现Web功能的都需要实现WenMvcConfigurer接口
public class MyInterceptorConfig implements WebMvcConfigurer {
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor())
                // 拦截哪些请求
                .addPathPatterns("/**")
                // 放过哪些请求
                .excludePathPatterns("/login");
    }
}

拦截器原理

1、根据当前请求找到 HandlerExecutionChain【可以处理当前请求的hander及所有拦截器】
在这里插入图片描述

2、拿到这个 HandlerExecutionChain 后执行 applyPreHandle 方法

if (!mappedHandler.applyPreHandle(processedRequest, response)) {
    // 如果下面的方法返回false,请求结束
    return;
}
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
    // 正向循环所有拦截器
    for (int i = 0; i < this.interceptorList.size(); i++) {
        HandlerInterceptor interceptor = this.interceptorList.get(i);
        // 执行preHandle方法
        if (!interceptor.preHandle(request, response, this.handler)) {
            triggerAfterCompletion(request, response, null);
            // 如果方法返回false,返回false
            return false;
        }
        this.interceptorIndex = i;
    }
    // 如果方法返回true,返回true
    return true;
}

3、执行目标方法

mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

4、执行HandlerExecutionChain 的applyPostHandle 方法

mappedHandler.applyPostHandle(processedRequest, response, mv);
// 同样的逻辑,反向循环所有拦截器,执行 postHandle方法
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv)
    throws Exception {
    for (int i = this.interceptorList.size() - 1; i >= 0; i--) {
        HandlerInterceptor interceptor = this.interceptorList.get(i);
        interceptor.postHandle(request, response, this.handler, mv);
    }
}

整体流程图如下:
在这里插入图片描述
以上就是Spring MVC 拦截器的整个内容

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页