SpringBoot 拦截器

作者: 我是曾经那个少年 | 来源:发表于2019-04-21 23:17 被阅读20次

Interceptor可以在请求处理之前,请求处理之后进行干预,所以我们可以利用拦截器的特性进行一些例如日志打印,身份认证和授权,错误管理,接口限流等。

1 使用拦截器

  1. 通过实现HandlerInterceptor接口自定义拦截器。
  2. 添加自定义拦截器到WebMvcConfigurerAdapter

1.1 实现自定义拦截器

我们打印出日志查看拦截器执行的顺序。

public class UriInterceptor implements HandlerInterceptor{
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        logger.info("UriInterceptor preHandle controller 执行之前");
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        logger.info("UriInterceptor postHandle controller 执行之后,渲染视图之前");
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        logger.info("UriInterceptor afterCompletion  渲染视图之后");      
    }
}

1.2 添加自定义拦截器到WebMvcConfigurerAdapter

@Configuration
public class WebMvcConfigurer extends WebMvcConfigurerAdapter{
    @Bean
    public UriInterceptor uriInterceptor(){
        return new UriInterceptor();
    }
    /* 
     * 自定义拦截器添加到拦截器链中
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // addPathPatterns("/**");匹配所有请求
        // addPathPatterns("*.do");匹配.do结尾的请求
        registry.addInterceptor(uriInterceptor()).addPathPatterns("/**");
        super.addInterceptors(registry);
    }
}

1.3 请求测试

    @GetMapping("index")
    public String demo(){
        logger.info("DemoController index 正在执行!");
        return "查看拦截器的顺序";
    }

查看执行日志记录

请求先到拦截器的preHandle,再到控制器,再到postHandle ,再到afterCompletion 。

 [nio-8080-exec-1] c.l.s.web.interceptor.UriInterceptor     : UriInterceptor preHandle controller 执行之前
[nio-8080-exec-1] c.l.s.web.controller.DemoController      : DemoController index 正在执行!
 [nio-8080-exec-1] c.l.s.web.interceptor.UriInterceptor     : UriInterceptor postHandle controller 执行之后,渲染视图之前
 [nio-8080-exec-1] c.l.s.web.interceptor.UriInterceptor     : UriInterceptor afterCompletion  渲染视图之后

2 我们通过拦截器实现登录验证?

  1. 定义接口白名单,例如首页,登录页,问题页,部分活动页不需要登录授权就可以访问。
  2. 获取token。
  3. token校验。

token的生成规则可以参考标准的JWT,或者自己内部定义即可。

一般包括如下信息:用户标识信息,时间戳,签名算法,随机数

例如 UID+时间戳(13位)+MD5+随机数

    // 定义接口白名单
    private static String[] INTERFACE_WHITE_LIST = {"login","index"};

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        logger.info("UriInterceptor preHandle controller 执行之前");
        String requestUri = request.getRequestURI();
        // 如果在接口白名单之前放行
        if (isWhilteList(requestUri)) {
            return true;
        }
        // 方案一  从请求头获取token
        String token = request.getHeader("token");
        // 方案二  从cookie获取token
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("token")) {
                token = cookie.getValue();
            }
        }
        // token校验
        if (isMatch(token,request)) {
            // 判断token是否符合规则
            // token解析
            // 判断token是否正确
            // 判断token是否过期
            // 把用户信息放入request请求中
        }
        return false;
    }

多个拦截器是怎么执行的?大家可以尝试一下,其实就是你添加到拦截器链中的先后顺序决定。

源码下载 :Github

传送门SpringBoot学习总结系列文章

相关文章

网友评论

    本文标题:SpringBoot 拦截器

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