1.创建一个SpringBoot项目,模拟用户登录
```java
@Controller
@RequestMapping("/user")
public class UserController {
//用户登录的请求
@RequestMapping(value = "/login")
public @ResponseBody Object login(HttpServletRequest request){
User user=new User();
user.setId(1001);
user.setName("zhangsan");
//将用户的信息存放的session中
request.getSession().setAttribute("user",user);
return "login SUCCESS";
}
//该请求需要用户登录之后才可访问
@RequestMapping(value = "/center")
public @ResponseBody Object center(){
return "See Center Message";
}
//不登陆也可以访问
@RequestMapping(value = "/out")
public @ResponseBody Object out(){
return "Everyone can see";
}
//如果用户未登录就访问了需要登录才可访问的请求,之后会跳转到该请求路径
@RequestMapping(value = "/error")
public @ResponseBody Object error(){
return "error";
}
}
2.创建拦截器类实现HandlerInterceptor接口
public class UserInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("进入拦截器的preHandle()----------");
//从session中获取用户信息
User user= (User) request.getSession().getAttribute("user");
if(user==null){
//未登录
response.sendRedirect(request.getContextPath()+"/user/error");
return false;
}
//已登录
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
System.out.println("进入拦截器的postHandle()------------");
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
System.out.println("进入拦截器的afterCompletion()------------");
}
}
3.配置拦截器
@Configuration //定义此类为配置文件(即相当于之前的xml配置文件)
public class InterceptorConfig implements WebMvcConfigurer{
public void addInterceptors(InterceptorRegistry registry) {
String[] addPathPatterns={
"/user/**" //表示要拦截user下的所有访问请求,必须用户登录后才能访问
};
//要排除的路径,排除的路径说明不需要用户登录也可以访问
String[] excludePathPatterns={
"/user/out",
"/user/error",
"/user/login"
};
registry.addInterceptor(new UserInterceptor()).addPathPatterns(addPathPatterns).excludePathPatterns(excludePathPatterns);
}
}
运行,看控制台
可以看到,拦截器中的方法将按preHandle->Controller->postHandle->afterCompletion的顺序执行.并且只有preHandle方法返回true时后面的方法才会执行.当拦截器链内存在多个拦截器时,postHandler在拦截器链内的所有拦截器返回成功时才会调用,而afterCompletion只有preHandle返回true才调用,但若拦截器链内的第一个拦截器的preHandle方法返回false,则后面的方法都不会执行.