一、HandlerInterceptorAdapter类
Springboot 的拦截器概念上和Filter 很像,拦截发送到 Controller 的请求和给出的响应;HandlerInterceptorAdapter类提供了请求处理的3个方法;
//拦截于请求刚进入时,进行判断,需要boolean返回值,如果返回true将继续执行,如果返回false,将不进行执行。一般用于登录校验
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; }
//拦截于方法成功返回后,视图渲染前,可以对modelAndView进行操作 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { }
//拦截于方法成功返回后,视图渲染前,可以进行成功返回的日志记录 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { }
//不是HandlerInterceptor的接口实现,是AsyncHandlerInterceptor的,AsyncHandlerInterceptor实现了HandlerInterceptor
public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
}
详解:
(1)、preHandle (HttpServletRequest request, HttpServletResponse response, Object handle) 方法。顾名思义,该方法将在请求处理之前进行调用。SpringMVC中的Interceptor是链式的调用的,在一个应用中或者是在一个请求中可以同时存在多个Interceptor。每个Interceptor的调用会依据它的声明顺序依次执行,而且最先执行的都是Interceptor中的preHandle 方法,所以可以在这个方法中进行一些前置初始化操作或者是对当前请求的一个预处理,也可以在这个方法中进行一些判断来决定请求是否要继续进行下去。该方法的返回值是Boolean类型的,当它返回为false时,表示请求结束,后续的Interceptor和Controller都不会再执行;当返回值为true 时就会继续调用下一个Interceptor的preHandle方法,如果已经是最后一个Interceptor的时候就会是调用当前请求的Controller 方法。
(2)、postHandle (HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView) 方法。由preHandle方法的解释我们知道这个方法包括后面要说到的afterCompletion方法都只能是在当前所属的Interceptor的preHandle方法的返回值为true时才能被调用。postHandle方法,顾名思义就是在当前请求进行处理之后,也就是Controller方法调用之后执行,但是它会在DispatcherServlet进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller处理之后的ModelAndView对象进行操作。postHandle方法被调用的方向跟preHandle是相反的,也就是说先声明的Interceptor的postHandle方法反而会后执行。
(3)、afterCompletion (HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex) 方法,该方法也是需要当前对应的Interceptor的preHandle方法的返回值为true时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。
二、鉴权AuthInterceptor
继承HandlerInterceptorAdapter类,重写了preHandle方法,对请求登录人角色进行权限鉴定;
@Slf4j public class AuthInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { request.setCharacterEncoding("UTF-8"); if (true) { return super.preHandle(request, response, handler); } throw new AuthException(EnumResult.PERMISSION_ERROR); } }
三、注册拦截器
注册拦截器很简单,只需要配置一个类,使其实现 WebMvcConfigurer 接口即可;其中还可以设定多个不同的拦截器,并且映射到不同的 url 地址上。
@EnableWebMvc @Configuration public class InterceptorConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new AuthInterceptor())//添加拦截器 .addPathPatterns("/**") .excludePathPatterns("/login"); } }
注:addPathPatterns("/**")对所有请求都拦截;excludePathPatterns("/login")方法是排除登录访问路径;
更多关于interceptor参见: