拦截器
一. 拦截器的概念
简单来理解拦截器 ,举个例子:任何人进入大学校门要经过保安的拦截和检查(进行人脸识别),在出校门的时候在人脸识别一次,其中这进大门和出大门进行拦截的过程就是拦截器,如果拦截器返回true,表示识别捅过,进行放行,进入程序开始执行,如果拦截器放回false,则直接拦截,不在进行后续操作。
拦截器主要用于检测传入的URL是否正确。
拦截器的运行整体过程如下图所示:
在URL传入时进行拦截,通过Session判断数据是否正确,正确则进入Controller开始执行,不正确则直接拦截,出来时还要再次拦截识别一次。
二. 拦截器的实现
拦截器的使用步骤分为两步:
- 定义拦截器
- 注册配置拦截器
2.1 定义拦截器
定义拦截器就是相当于建立了校园的大门口,注册配置拦截器就相当于是配置保安进行上岗。
首先是创建一个类实现HandlerInterceptor接口,然后重写HandlerInterceptor接口的两个方法,其中重写的preHandle方法就是进校门时候的拦截,另一个重写的postHandle方法是出校门的拦截,最后一个方法afterCompletion表示的是进行视图渲染,目前我们不在要求学习视图渲染。
自定义拦截器:实现HandlerInterceptor接口,并重写其所有方法
拦截器代码如下:
@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponseresponse, Object handler) throws Exception {
log.info("LoginInterceptor 目标方法执行前执行..");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponseresponse, Object handler, ModelAndView modelAndView) throws Exception {
log.info("LoginInterceptor 目标方法执行后执行");
}
@Override
public void afterCompletion(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex) throws Exception {
log.info("LoginInterceptor 视图渲染完毕后执行,最后执行");
}
}
- preHandle()方法:目标方法执行前执行.返回true:继续执行后续操作;返回false:中断后续操作.
- postHandle()方法:目标方法执行后执行
- afterCompletion()方法:视图渲染完毕后执行,最后执行(后端开发现在⼏乎不涉及视图,暂不了 解)
2.2 注册配置拦截器
定义拦截器就是相当于建立了校园的大门口,注册配置拦截器就相当于是配置保安进行上岗。在这里就相当于是分配保安进行上岗,在代码是表现中就是把定义的拦截器添加进MVC,让Spring来进行管理分配,然后在配置一个拦截路径,就相当于与你保安可以拦截学生但肯定不能拦截校领导,一拦一个不吱声…,这时候就在配置一个不拦截的路径。
注册配置拦截器:实现WebMvcConfigurer接⼝,并重写addInterceptors方法
实现代码如下:
@Configuration
public class WebConfig implements WebMvcConfigurer {
//⾃定义的拦截器对象
@Autowired
private LoginInterceptor loginInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//注册⾃定义拦截器对象
registry.addInterceptor(loginInterceptor)
.addPathPatterns("/**");//设置拦截器拦截的请求路径( /** 表⽰拦截所有请求)
}
}
然后我们进行运行代码,启动服务,试试访问任意请求,观察后端日志
可以看到preHandle方法执行之后就放行了,开始执行目标方法,目标方法执行完成之后执行postHandle和afterCompletion方法.
2.3 拦截路径
拦截路径是指我们定义的这个拦截器,对哪些请求⽣效.
我们在注册配置拦截器的时候,通过 addPathPatterns() 方法指定要拦截哪些请求.也可以通excludePathPatterns() 指定不拦截哪些请求.
在拦截器中除了可以设置 /** 拦截所有资源外,还有⼀些常见拦截路径设置:
拦截路径 | 含义 | 举例 |
---|---|---|
/* | ⼀级路径 | 能匹配/user,/book,/login,不能匹配/user/login |
/** | 任意级路径 | 能匹配/user,/user/login,/user/reg |
/book/* | /book下的⼀级路径 | 能匹配/book/addBook,不能匹配/book/addBook/1,/book |
/book/** | /book下的任意级路径 | 能匹配/book,/book/addBook,/book/addBook/2,不能匹配/user/login |
三. 拦截器执行流程
-
添加拦截器后,执行Controller的方法之前,请求会先被拦截器拦截住.执行 preHandle() 方法,这个方法需要返回⼀个布尔类型的值.如果返回true,就表示放行本次操作,继续访问controller中的方法.如果返回false,则不会放行(controller中的方法也不会执行).
-
controller当中的方法执行完毕后,再回过来执行 postHandle() 这个方法以及afterCompletion() 方法,执行完毕之后,最终给浏览器响应数据.