springboot 实现拦截器功能
最近在写springboot的一个拦截器 网上很多文章了 总体来说比较简单理解,但是可能由于没看到比较合适的,就自己写了一个 简单的实现了自己的需求。里面加了角色的判断 还有访问路径不同的判断。因为只是练手demo 没有写的很好。以博客系统为例:管理员 角色是admin ,作者角色是 author.
需求1.直接访问登陆页(/logIn) 登录 跳到主页(管理员跳到admin/index,作者跳到author/index)
2.直接回车访问 例如localhost:8080/ 跳到login页面 登录后到主页(管理员跳到admin/index,作者跳到author/index)
3.访问一个特定页面 例如:待审核文章的页面 localhost:8080/author/article_wait_list 应该跳到登陆页,登录成功后 跳到article_wait_list 这个页面
4.admin 角色的只能访问admin 的页面 author 的只能访问author下的页面
1.实现HandlerInterceptor
public class MyLoginCheckInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 用户访问的路径
String getUrl = request.getRequestURI();
if (getUrl.equals("/")) {
getUrl = "noUrl";
}
// 获取用户角色信息
HttpSession session = request.getSession();
String name = (String) session.getAttribute("username");
String role = (String) session.getAttribute("role");
System.out.println("拦截器" + getUrl + "/" + role + "/" + name);
// 判断是否登录
if (null == name || name.equals("")) {
session.setAttribute("purUrl", getUrl);
response.sendRedirect("/logIn");
return false;
} else {
// 已登录 区分角色
if (getUrl.contains("/admin") && role.equals("admin")) {
return true;
} else if (getUrl.contains("/author") && role.equals("author")) {
return true;
} else {
System.out.println("权限不对,");
return false;
}
}
}
}
2.注册该拦截器,注意:1. @Configuration
2. excludePathPatterns("/error")配置一下 不然假如你的网页里面有图片或别的资源请求不到会返回spring的erroer
@Configuration
public class WebMyConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
System.out.println("请求到了-------");
registry.addInterceptor(new MyLoginCheckInterceptor()).addPathPatterns("/**").excludePathPatterns("/login")
.excludePathPatterns("/css/**").excludePathPatterns("/js/**").excludePathPatterns("/img/**")
.excludePathPatterns("/logIn").excludePathPatterns("/loginOut").excludePathPatterns("/error");
}
}
3.写登录controller,此处注意 Object url = session.getAttribute("purUrl");的判断 因为直接访问login这个url的时候, .excludePathPatterns("/login") ,没有经过拦截器,所以session是null
@Controller
public class LoginController {
@Autowired
private AccountService accountService;
@GetMapping("/logIn")
public String login() {
return "/login";
}
@GetMapping("/login")
public String login3() {
return "/login";
}
@PostMapping("/login")
public String login2(@RequestParam(required = true) String username, @RequestParam(required = true) String password,
HttpServletRequest request, HttpServletResponse response) {
Account acc = accountService.selectAccountExits(username, password);
HttpSession session = request.getSession();
Object url = session.getAttribute("purUrl");
String goUrl=null;
if(null ==url) {
goUrl="noUrl";
}else {
goUrl=url.toString();
}
if (null != acc) {
session.setAttribute("username", acc.getUsername());
session.setAttribute("role", acc.getRole());
if (goUrl.equals("noUrl")) {
return "redirect:" + acc.getRole() + "/index";
} else {
return "redirect:" + url;
}
} else {
return "/login";
}
}
@GetMapping("/loginOut")
public String loginOut(HttpServletRequest request) {
HttpSession session = request.getSession();
session.removeAttribute("username");
session.removeAttribute("role");
session.removeAttribute("purUrl");
return "/login";
}
}
测试发现 自己想要的功能都有了,当然你业务逻辑简单也可以不这么复杂,直接不管访问那个页面都放回到主页也可以。但是拦截器,权限什么的最好是学习spring里面的Spring Security。