Spring
中提供了具体的实现拦截器:
HandlerInterceptor
,拦截器的实现分为以下两个步骤:
1.
创建自定义拦截器,实现
HandlerInterceptor
接口的
preHandle
(执行具体方法之前的预处理)
方法。
2.
将自定义拦截器加入
WebMvcConfigurer
的
addInterceptors
方法中。
演示用户登录权限的校验:
1.自定义拦截器
// 如果用户未登录,则直接重定向到登录页,不会走到后续操作
@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Autowired
public LoginInterceptor() {
log.info("LoginInterceptor.LoginInterceptor()");
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("LoginInterceptor.preHandle()");
Object currentUser = null;
HttpSession session = request.getSession(false);
if (session != null) {
currentUser = session.getAttribute("currentUser");
}
if (currentUser == null) {
// 说明用户未登录
log.info("LoginInterceptor.preHandle: 用户未登录,重定向到 登录页(/login.html)");
response.sendRedirect("/login.html");
//位
return false;
}
log.info("LoginInterceptor.preHandle: 用户登录了,继续后续操作。当前用户: {}", currentUser);
//位true就可以继续的往下执行
return true;
}
@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 {
}
}
1. 有个拦截器对象(自己new 或者 交给 Spring)
2. 需要将对象注册,并且关联到某些 URL(哪些 URL 会应用拦截器),通过 WebConfigurator bean 来注册
@Slf4j
// 1. 必须是一个 Spring bean(否则没有机会调用)
// 2. 必须实现了 WebMvcConfigurer 接口
@Configuration
public class WebConfig implements WebMvcConfigurer {
// 由于我们的拦截器已经注册给 Spring 了,所以,可以使用注入的方式
private final LoginInterceptor loginInterceptor;
@Autowired
public WebConfig(LoginInterceptor loginInterceptor) {
this.loginInterceptor = loginInterceptor;
log.info("WebConfig.WebConfig()");
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 在这个方法中注册拦截器
registry.addInterceptor(loginInterceptor)
.addPathPatterns("/**") // 应用到所有 URL 上
.excludePathPatterns("/error") // 只要有错误,都会到这
.excludePathPatterns("/login.do")
.excludePathPatterns("/login.html"); // 但是 /login.html 是例外
// 先添加的拦截器,先被应用
log.info("WebConfig.addInterceptors()");
}
}
对应的网页的入口
@Slf4j
@Controller
public class LoginDoController {
@Autowired
public LoginDoController() {
log.info("LoginDoController.LoginDoController()");
}
@PostMapping("/login.do")
public String login(String username, String password, HttpSession session) {
Map<String, String> user = new LinkedHashMap<>();
user.put("username", username);
user.put("password", password);
session.setAttribute("currentUser", user);
log.info("LoginDoController.login: 登录成功,重定向到首页(/)");
return "redirect:/";
}
}