在实际开发中我们需要实现一些类似于登录拦截的功能,防止用户未经登录直接访问我们的网站。
首先我们创建一个拦截器类LoginInterceptor,并实现HandlerInterceptor接口
/**
* @Author Kk
* @Date 2022/2/6 14:00
* @Description 配置拦截器实现登录拦截
* 1.配置好拦截器要拦截那些请求
* 2.把这些配置放到容器中
*/
public class LoginInterceptor implements HandlerInterceptor {
/**
* 目标方法执行之前
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@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("/").forward(request,response);
return false;
}
/**
* 目标方法执行完成以后
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
/**
* 页面渲染之后
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
接下来,我们需要将拦截器添加到容器中。
因此我们可以创建一个配置类AdminWebConfig,并且实WebMvcConfigurer接口
/**
* @Author Kk
* @Date 2022/2/6 14:16
* @Description
*/
@Configuration
public class AdminWebConfig implements WebMvcConfigurer {
//重写WebMvcConfigurer 接口中的addInterceptors方法
//将我们自己定义的拦截器注册进去
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**") //要拦截的路径
.excludePathPatterns("/","/login","/css/**","fonts/**","/images/**","/js/**"); //避免拦截的路径
}
}
重启服务,这样我们的拦截器便生效了
拦截器原理
1、根据当前请求,找到HandlerExecutionChain【可以处理请求的handler以及handler的所有 拦截器】
2、先来顺序执行 所有拦截器的 preHandle方法
● 1、如果当前拦截器prehandler返回为true。则执行下一个拦截器的preHandle
● 2、如果当前拦截器返回为false。直接 倒序执行所有已经执行了的拦截器的 afterCompletion;
3、如果任何一个拦截器返回false。直接跳出不执行目标方法
4、所有拦截器都返回True。执行目标方法
5、倒序执行所有拦截器的postHandle方法。
6、前面的步骤有任何异常都会直接倒序触发 afterCompletion
7、页面成功渲染完成以后,也会倒序触发 afterCompletion