拦截器(Interceptor)
概念:是一种动态拦截方法调用的机制,类似于过滤器。Spring框架中提供的,用来动态拦截控制器方法的执行。
作用:拦截请求,在指定的方法调用前后,根据业务需要执行预先设定的代码。

快速入门
定义拦截器
实现HandlerInterceptor接口,并重写其所有方法。
@Component
public class LoginInterceptor implements HandlerInterceptor {
    @Override //目标方法执行前的执行,返回true放行,返回false不放行
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }
    @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);
    }
}注册拦截器
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    LoginInterceptor loginInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor).addPathPatterns("/**");
    }
}拦截器-拦截路径

| 拦截路径 | 含义 | 举例 | 
| /* | 一级路径 | 能匹配/depts,/emps,/login,不能匹配 /depts/1 | 
| /** | 任意级路径 | 能匹配/depts,/depts/1,/depts/1/2 | 
| /depts/* | /depts下的一级路径 | 能匹配/depts/1,不能匹配/depts/1/2,/depts | 
| /depts/** | /depts下的任意级路径 | 能匹配/depts,/depts/1,/depts/1/2,不能匹配/emps/1 | 
拦截器-执行流程

Filter与Interceptor区别
- 接口规范不同:过滤器需要实现Filter接口,而拦截器需要实现HandlerInterceptor接口。
- 拦截范围不同:过滤器Filter会拦截所有的资源,而Interceptor只会拦截Spring环境中的资源。
登录验证
- 获取请求url。 判断请求url中是否包含login,如果包含,说明是登录操作,放行。
- 获取请求头中的令牌(token)。
- 判断令牌是否存在,如果不存在,返回错误结果(未登录)。
- 解析token,如果解析失败,返回错误结果(未登录)。
- 放行。
                                     
 
Interceptor的实现
@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {
    @Override //目标方法执行前的执行,返回true放行,返回false不放行
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取url
        String url = request.getRequestURL().toString();
        log.info("url路径:{}",url);
        //获取token
        String token = request.getHeader("token");
        log.info("token:{}",token);
        //如果没有Token
        if (!StringUtils.hasLength(token)) {
            extracted(response);
            return false;
        }
        //解析token
        try {
            JwtUtils.parseJwt(token);
        } catch (Exception e) {
            e.printStackTrace();
            extracted(response);
            return false;
        }
        return true;
    }
    private void extracted(HttpServletResponse response) throws IOException {
        Result noLogin = Result.error("用户未登录");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write(JSONObject.toJSONString(noLogin));
    }
    @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);
    }
}
配置Interceptor
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    LoginInterceptor loginInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor).addPathPatterns("/**").excludePathPatterns("/login");
    }
}测试

 





![[Netty源码] ByteBuf相关问题 (十)](https://img-blog.csdnimg.cn/66961cf9dedf4caaa1f95334da4ddf7a.png)













