拦截器是基于 Java 反射机制实现的,因此拦截器只能拦截实现了接口的类,而不能拦截 url 这种链接。只能拦截部分 web 请求
在 Dispatcher 的 doDispatch方法中被调用。找到 Handler 和HandlerAdapter之后执行
Interceptor 中的方法执行顺序为 preHandle – Controller 方法 – postHandle – afterCompletion ,所以拦截器实际上可以对 Controller 方法执行前后进行拦截监控。
// 1. 先找 Handler
mappedHandler = this.getHandler(processedRequest);
// 2. 根据 Handler类型匹配 HandlerAdapter
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
// 3. 调用拦截器PreHandle
if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; }
// 4. 执行 Controller 层方法中的逻辑
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
// 5. 调用拦截器postHandle
mappedHandler.applyPostHandle(processedRequest, response, mv);
// 拦截器执行逻辑
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
for(int i = 0; i < this.interceptorList.size(); this.interceptorIndex = i++) {
HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i);
if (!interceptor.preHandle(request, response, this.handler)) {
this.triggerAfterCompletion(request, response, (Exception)null);
return false;
}
}
return true;
}
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv) throws Exception {
for(int i = this.interceptorList.size() - 1; i >= 0; --i) {
HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i);
interceptor.postHandle(request, response, this.handler, mv);
}
}
使用拦截器
创建拦截器
实现 HandlerInterceptor
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println(new Date() + "--preHandle:" + request.getRequestURL());
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println(new Date() + "--postHandle:" + request.getRequestURL());
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println(new Date() + "--afterCompletion:" + request.getRequestURL());
}
}
配置拦截器
WebMvcConfigurer实现类中添加拦截器
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Resource
private MyInterceptor myInterceptor;
/**
* 添加Web项目的拦截器
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myInterceptor).addPathPatterns("/**")
.excludePathPatterns("/", "/login", "/index.html", "/user/login", "/css/**", "/images/**", "/js/**", "/fonts/**");
}
}
拦截器的种类
MethodInterceptor
HandlerInterceptor