美文网首页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