拦截器
拦截器基于Java的反射机制,属于面向切面编程(AOP)的一种运用,就是在service或者一个方法前,调用一个方法,或者在方法后,调用一个方法,比如动态代理就是拦截器的简单实现,在调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在调用方法后打印出字符串,甚至在抛出异常的时候做业务逻辑的操作。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理。
项目结构
用户首次访问项目中的路径时,会被拦截器拦截,然后跳转到登录页面index.html。在登录页面输入的用户名密码,post提交请求后进去controller中的login方法进行登录验证,验证成功,则以cookie保持登录状态。
1 创建拦截器
@Component
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("进入拦截器");
Cookie[] cookies = request.getCookies();
if(cookies!=null && cookies.length>0){
for(Cookie cookie:cookies) {
log.debug("cookie===for遍历"+cookie.getName());
if (StringUtils.equalsIgnoreCase(cookie.getName(), "isLogin")) {
log.debug("有cookie ---isLogin,并且cookie还没过期...");
//遍历cookie如果找到登录状态则返回true继续执行原来请求url到controller中的方法
return true;
}
}
}
log.debug("没有cookie-----cookie时间可能到期,重定向到登录页面后请重新登录。。。");
//这里必须得能定位到html文件才行,放在static文件夹下可以直接访问到。或者直接"/",这意味着请求index.html
//response.sendRedirect("/html/login.html");
response.sendRedirect("/");
return false;
}
@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 {
}
}
2 Spring注册拦截器
创建后的拦截器需要注册到spring容器中才能使用,这需要用到configuration这个配置注解。在addInterceptors方法中可以设置拦截路径,以及不拦截的路径。此处我们不拦截登录时需要用到的页面index.html以及登录方法Login。
@Configuration
public class WebConfigure implements WebMvcConfigurer {
// 这个方法是用来配置静态资源的,比如html,js,css,等等
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
}
// 这个方法用来注册拦截器,我们自己写好的拦截器需要通过这里添加注册才能生效,可以注册多个拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
//不知道这种为啥不能同时拦截teacher与studnet
/* registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/teacher/**","/studnet/**")
.excludePathPatterns("/login","/index.html");*/
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/student/**").addPathPatterns("/teacher/**")
.excludePathPatterns("/login","/index.html");
}
}
3 登录页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div align="center">
<h1>学生管理系统登录</h1>
<form action="/login" method="post">
账号:<input type="text" name="name1" placeholder="请输入账号"><br>
密码:<input type="password" name="pass1" placeholder="请输入密码"><br>
<input type="submit" value="登录">
</form>
</div>
</body>
</html>
4 登录方法
@Controller
@Slf4j
@RequestMapping(value = "/")
public class LoginController {
@Autowired
private TeacherService teacherService;
@PostMapping(value = "/login")
public String test(HttpServletRequest request, HttpServletResponse response, @RequestParam("name1")String name, @RequestParam("pass1")String pass) throws Exception{
try {
System.out.println("开始登录查询----------------------------");
List<User> result = teacherService.findByIdAndPass(name,pass);
if(result==null || result.size()==0){
log.debug("账号或者密码不正确或者此人账号没有注册");
throw new Exception("账号或者密码不正确或者此人账号没有注册!");
}else{
log.debug("查询满足条数----"+result);
Cookie cookie = new Cookie("isLogin", "success");
cookie.setMaxAge(30);
cookie.setPath("/");
response.addCookie(cookie);
request.setAttribute("isLogin", name);
log.debug("首次登录,查询数据库用户名和密码无误,登录成功,设置cookie成功");
//设置登录成功后跳转的页面,读者可根据自己的情况自己设计返回页面。
return "redirect:/teacher/list";
}
} catch (DataAccessException e) {
e.printStackTrace();
return "error1";
}
}