完成请求拦截也非常简单。思路和解决方案,代码以及重定向次数过多问题如下。
(1)对请求的url进行过滤,可以使用过滤器去实现IP黑白名单。(2)通过session的getAttribute()方法取对应属性进行非空判断,空的话进行拦截
(3)使用token方式进行请求权限认证
主讲第二种方法:场景为登录场景。先理清下思路。
什么时候进行拦截?(session为空时)。
怎么知道session为空?(通过request.getsession. getAttribute()。
什么时候用session存我们要放的值。(登录页面不需要拦截,登录验证通过)
两个核心接口
HandlerInterceptor接口,提供对请求路由之前进行验证的操作。
WebMvcConfigurer接口,提供配置拦截器的方法。
代码:
首先提供登录验证接口
@Controller
public class LoginController {
@Autowired
private UserSer userSer;
@Autowired
private ManagerSer managerSer;
@RequestMapping("/login")
public String login(HttpServletRequest request){
String username = request.getParameter("username");
String password = request.getParameter("password");
String type = request.getParameter("types");
if(type.equals("0")){
System.out.println("普通用户认证===");
//普通用户认证
Bx_user user = userSer.findMyInfo(username);
if (user == null){
request.setAttribute("msg","用户名或密码不正确");
return "user/login";
}
if (user.getPassword().equals(password)){
System.out.println("set session value");
request.getSession().setAttribute("user",user);
return "redirect:/view/toIndex";
}else {
request.setAttribute("msg","用户名或密码不正确");
return "user/login";
}
}else{
//管理员认证
Bx_manager manager = managerSer.selectByName(username);
if (manager == null){
request.setAttribute("msg","用户名或密码不正确");
return "user/login";
}
if (manager.getPassword().equals(password)){
request.getSession().setAttribute("user",manager);
return "manager/index";
}else {
request.setAttribute("msg","用户名或密码不正确");
return "user/login";
}
}
}
@RequestMapping("/loginout")
public String loginout(HttpServletRequest request){
request.getSession().invalidate();
return "user/login";
}
}
其次提供HandlerInterceptor接口的实现方法,主要在pre方法实现。
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 检查每个到来的请求对应的session域中是否有登录标识
Object loginName = request.getSession().getAttribute("user");
if (null == loginName) {
// 未登录,重定向到登录页
response.sendRedirect("/view/toLogin");
return false;
}
logger.info("当前用户已登录,登录的用户名为: " + loginName);
return true;
}
再实现WebMvcConfigurer接口配置下拦截器
@Configuration
public class LoginConfiguration implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册拦截器
LoginInterceptor loginInterceptor = new LoginInterceptor();
InterceptorRegistration loginRegistry = registry.addInterceptor(loginInterceptor);
// 拦截路径
loginRegistry.addPathPatterns("/**");//.excludePathPatterns("/view/toLogin","/login","/view/toReg","/loginout");
// 排除路径
loginRegistry.excludePathPatterns("/login");
loginRegistry.excludePathPatterns("/loginout");
loginRegistry.excludePathPatterns("/view/toLogin");
loginRegistry.excludePathPatterns("/view/toReg");
loginRegistry.excludePathPatterns("/user/UserReg");
loginRegistry.excludePathPatterns("/static/user/css/*.css");
loginRegistry.excludePathPatterns("/static/user/js/*.js");
loginRegistry.excludePathPatterns("/static/user/images/*");
}
}
注意的地方:配置拦截器的不拦截的路径时,这个很重要。如果没配或者说配错的话都会有一个问题出现。就是重定向次数过多,导致网页无法响应。追究到底的原因就是:
我的拦截器参数配置是对所有的请求都进行拦截。所以请求过来时都进入LoginIntercetor的preHandle方法,实现里面的逻辑。逻辑判断就是session为空时,重定向到登录页面。
那么在这个时候,重定向是会重新发送一个请求的,请求地址是会变的,此时请求地址应该变为,在这个时候会重新发一个请求,因为这也是一个映射。那么这个时候会重新进入拦截器。此时还是对这个路径进行拦截,因为session一直为空。所以无限死循环了,这个时候就出现了重定向次数过多的问题。解决方法,就是在配置拦截器的拦截请求中,除去这个路径不对此进行拦截。这样就能实现正常拦截了。