1. 拦截器的作用
- 拦截器主要用来拦截用户的请求,在指定方法的前后根据业务执行预先设定的代码。
- 在拦截器中,可以在应用程序中做一些通用性的操作,比如通过拦截器来拦截前端发来的请求,判断session中是否有登录用户的信息,如果有就放行,没有就拦截,从而实现强制登录。
2. 拦截器的使用
- 定义拦截器
- 注册配置拦截器
自定义拦截器:实现HandlerInterceptor接口,重写其所有的方法。
@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// ture 表示放行, false:拦截
log.info("LoginInterceptor preHandle 目标方法执行前执行...");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("LoginInterceptor postHandle 目标方法执行后执行...");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
log.info("LoginInterceptor afterCompletion 视图渲染完成后执行,最后执行...");
}
}
- preHandle() 方法:目标方法执行前执行,返回true:继续执行后续操作;返回false:中断后续操作。
- postHandler() 方法:目标方法执行后执行。
- afterCompletion() 方法:视图渲染完成后执行,最后执行
注册配置拦截器:实现WebMvcConfigurer接口,注入拦截器依赖,重写addInterceptors()方法。
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//注册自定义拦截器对象
registry.addInterceptor(loginInterceptor)
.addPathPatterns("/**") //设置拦截器拦截的请求路径(/**表示拦截所有请求)
}
}
-
启动服务,访问任何请求,查看后端日志,
preHanler方法执行之后就开始执行目标方法,目标方法执行完后执行postHandler和afterCompletion方法。 -
当把拦截器中的preHandler方法的返回值改为false时,
-
拦截器拦截了请求,目标方法没有执行。
3. 拦截器的拦截配置路径
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/user/login") // 用户登录请求不拦截
}
}
-
addPathPatterns()方法表示拦截的请求,
- /** 表示拦截所有请求,如/user/login
- /* 表示拦截一级路径的请求/user,不能匹配/user/login
- /book/* 表示拦截/book下的一级路径,如/book/addBook,不能匹配/book/addBook/1
- /book/** 表示拦截/book下的任意路径,不能匹配非/book下的请求
-
excludePathPatterns()方法表示哪些请求不需要拦截。
4. 拦截器的处理流程(原理)
添加拦截器之后:
- 添加拦截器后,在执行Controller之前,请求会先被拦截器拦截住,执行拦截器中preHandler方法,这个方法需要返回一个布尔类型的值,如果该方法里面的返回值为true, 继续访问controller中的方法,如果返回false,则不会放行,controller中的方法也不会执行。
- controller当中的方法执行完成后,再过来执行postHandle()这个方法以及afterCompletion()方法,执行完之后最终给浏览器响应数据。