美文网首页springboot
SpringBoot 拦截器

SpringBoot 拦截器

作者: 拉提娜的爸爸 | 来源:发表于2019-09-29 09:11 被阅读0次

    学习参考:https://www.jianshu.com/p/51c5193b5883

    一、自定义一个拦截器

    1、实现拦截器

    • 实现HandlerInterceptor接口
    • 根据需求重写preHandle(),postHandle(),afterCompletion()方法
    package com.mystudy.springboot.interceptor;
    
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * 登录校验
     */
    public class LoginInterceptor implements HandlerInterceptor {
    
        /**
         * 方法在请求之前开始调用运行
         * @param request
         * @param response
         * @param handler
         * @return 返回true,表示继续流程,调用下一个拦截器或者处理器。返回false,表示流程中断,通过response产生响应。
         * 当方法返回false,后边的所有拦截器包括postHandle()、afterCompletion()都不在运行
         * @throws Exception
         */
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            Object userName = request.getSession().getAttribute("userName");
            if(userName==null){
                request.setAttribute("msg","请先登录");
                request.getRequestDispatcher("/index.html").forward(request,response);
    //            response.sendRedirect(request.getContextPath()+"/");
                return false;
            }
            return true;
        }
    
        /**
         * 方法在当前请求进行处理之后,就是controller运行完成之后被调用
         * @param request
         * @param response
         * @param handler
         * @param modelAndView
         * @throws Exception
         */
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    
        }
    
        /**
         * 方法在整个请求结束之后,就是在视图渲染完成后运行
         * 这个方法的主要作用是用于进行资源清理工作的。
         * @param request
         * @param response
         * @param handler
         * @param ex
         * @throws Exception
         */
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    
        }
    }
    
    

    2、注册拦截器

    • 实现WebMvcConfigurer接口
    • 重写addInterceptor()方法
    package com.mystudy.springboot.config;
    
    import com.mystudy.springboot.interceptor.LoginInterceptor;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.LocaleResolver;
    import org.springframework.web.servlet.config.annotation.*;
    
    @Configuration
    public class MyMvcConfig implements WebMvcConfigurer {
    
        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
            registry.addViewController("/").setViewName("login");
            registry.addViewController("/index.html").setViewName("login");
            registry.addViewController("/main.html").setViewName("dashboard");
        }
    
        /**
         * 注册拦截器 
         * @param registry
         */
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            // 注册拦截器
            InterceptorRegistration addInterceptor = registry.addInterceptor(new LoginInterceptor());
            // 配置拦截器路径
            addInterceptor.addPathPatterns("/**");
            // 配置不拦截路径,SpringBoot2.0以后静态资源映射会被拦截器拦截,所以需要取消静态资源的拦截
            // 取消webjars资源拦截器: webjars/**
            // 取消类路径下静态资源拦截: /js/**  /css/**  /img/**
            // 或者js、css、img放在同一文件夹asserts下, 则是:/asserts/**
            addInterceptor.excludePathPatterns("/user/login","/","/index.html","/asserts/**","/webjars/**");
    
        }
    
    }
    
    

    二、原理

    1、工作原理

    拦截器不是Filter,却实现了Filter的功能,其原理在于:

    • 所有的拦截器(Interceptor)和处理器(Handler)都注册在HandlerMapping中。
    • Spring MVC中所有的请求都是由DispatcherServlet分发的。
    • 当请求进入DispatcherServlet.doDispatch()时候,首先会得到处理该请求的Handler(即Controller中对应的方法)以及所有拦截该请求的拦截器。拦截器就是在这里被调用开始工作的。

    2、拦截器工作流程

    一个拦截器,只有preHandle方法返回true,postHandle、afterCompletion才有可能被执行;
    如果preHandle方法返回false,则该拦截器的postHandle、afterCompletion必然不会被执行。
    1)拦截器执行流程

    Interceptor1.preHandle → Interceptor2.preHandle → Controller处理请求 
    → Interceptor2.postHandle → Interceptor1.postHandle → 渲染视图 
    → Interceptor2.afterCompletion → Interceptor1.afterCompletion
    

    注意:两个拦截器在执行preHandle方法和执行postHandleafterCompletion方法时,顺序是颠倒的。

    2)和Filter共存时的执行顺序
    拦截器是在DispatcherServlet这个servlet中执行的,因此所有的请求最先进入Filter,最后离开Filter。其顺序如下。
    Filter->Interceptor.preHandle->Handler->Interceptor.postHandle->Interceptor.afterCompletion->Filter

    相关文章

      网友评论

        本文标题:SpringBoot 拦截器

        本文链接:https://www.haomeiwen.com/subject/uppqyctx.html