SpringMVC 拦截器
上篇笔记了记录了 SpringBoot 如何注入Servlet 三大组件,其中包括 Filter 的使用:SpringBoot 注册Servlet,Filter,Listener 这篇笔记要说的拦截器和 Filter 的作用其实差不多。
首先来说用法,要实现一个拦截器需要以下几步:
1、编写一个类实现 HandlerInterceptor 接口
public class MyInterceptor implements HandlerInterceptor {
/**
* 目标方法执行之前执行
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
Object loginUser = session.getAttribute("loginUser");
if (loginUser != null) {
return true
}
request.setAttribute("msg", "请先登录");
// 转发到登录页
request.getRequestDispatcher("/login").forward(request, response);
return false;
}
/**
* 目标方法执行之后执行
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
/**
* 页面渲染之后执行
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
2、把拦截器注入到容器中
@Configuration
// SpringBoot中所有定制实现Web功能的都需要实现WenMvcConfigurer接口
public class MyInterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor())
// 拦截哪些请求
.addPathPatterns("/**")
// 放过哪些请求
.excludePathPatterns("/login");
}
}
拦截器原理
1、根据当前请求找到 HandlerExecutionChain【可以处理当前请求的hander及所有拦截器】
2、拿到这个 HandlerExecutionChain 后执行 applyPreHandle 方法
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
// 如果下面的方法返回false,请求结束
return;
}
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 正向循环所有拦截器
for (int i = 0; i < this.interceptorList.size(); i++) {
HandlerInterceptor interceptor = this.interceptorList.get(i);
// 执行preHandle方法
if (!interceptor.preHandle(request, response, this.handler)) {
triggerAfterCompletion(request, response, null);
// 如果方法返回false,返回false
return false;
}
this.interceptorIndex = i;
}
// 如果方法返回true,返回true
return true;
}
3、执行目标方法
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
4、执行HandlerExecutionChain 的applyPostHandle 方法
mappedHandler.applyPostHandle(processedRequest, response, mv);
// 同样的逻辑,反向循环所有拦截器,执行 postHandle方法
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv)
throws Exception {
for (int i = this.interceptorList.size() - 1; i >= 0; i--) {
HandlerInterceptor interceptor = this.interceptorList.get(i);
interceptor.postHandle(request, response, this.handler, mv);
}
}
整体流程图如下:
以上就是Spring MVC 拦截器的整个内容