SpringBoot日记——登录与拦截器篇
之前的文章我们把登录页写了出来,但是想要让登录现实他的基本功能,要如何做呢?本篇文章就来帮你实现第一步,让登录页对账号密码做校验,并且完成登录跳转。
LoginController
1. 要实现登录,我们需要先编写一个登录的controller类:(每一步的注释应该比较详细了~)
@Controller public class LoginController { // 发送post请求,代替了RequestMapping(value="/user/login", method="post") @PostMapping(value = "/user/login") // 对登录请求判断request的参数值,并存放在map中 public String login(@RequestParam("username") String username, @RequestParam("password") String password, Map<String, Object> map) { // 我们判断,如果登录名不是空,并且,密码是 123456 就登录成功(暂不涉及数据库) if (!StringUtils.isEmpty(username) && "123456".equals(password)) { // 登录成功,就跳转到下一个页面 return "dashboard"; } else { // 登录失败,刷新本登录页 map.put("msg", "用户名密码错误"); return "login"; } } }
为了开发方便,我们还可以将application.properties中添加一个 禁用缓存的参数: spring.thymeleaf.cache=fasle ,这样html页面有改动的时候,我们只需要用快捷键crtl+F9或者点击如图的编译按钮,重新编译下就可以在页面看结果,而不需要再次启动Tomcat服务了。
这时候访问页面,会报错,是因为我们没有在html页面中将类中的参数放进去,所以找不到我们需要的值,那么……
2. 校验页面
先来看,没有配置html页时访问的情况,表示完全没有关联或者获取的页面的数据;
然后我们添加下方参数配置再看,若只添加action和method,会是神马情况:(表示String的参数username不存在)
最后看添加了所有参数后的情况,我们在最后看一下;
login.HTML
我们来看html页要如何修改呢?
来看,我图中标记的地方,就是需要添加的东西:
1. 首先添加th:action,告诉模板,我们要跳转的请求是user/login,而且是post请求的;
2.告诉模板,我们的参数名称是username和password,这也是controller类中设定的参数值,要完全一致。
3.注意,我们之前说如果账号密码不对,要有个msg提示,可这msg在模板中并没有表现,所以,我们要在html中添加一段关于msg的判断:如果msg是空,就不展示mgs,如果不为空就展示:
看,我在下方还用到了th:if语句,这个在官方文档中有记录如何使用,而且优先级比较高,所以会优先判断这个方法是否生效,然后才展示text。
<p style="color: red;" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
好,接下来我们试一下,是否成功了,先输入账号admin,密码111,点击登录,看跳转是否依然还是login页:
然后来看,账号admin,密码123456,是否跳转到下一页中:
我们的跳转是成功的,只是样式有些问题,稍后,我们来看怎么处理。
试图映射与重定向
跳转没问题了,可是还有另一个问题,当我们进入到跳转页以后,按F5刷新页面,会发现,页面提示:问是否需要重新提交表单,那么为了不重复提交表单,我们需要这样配置。
1. 首先在我们之前的LoginController类中添加映射:(修改return ,将我们的请求定向到另一个路径,而非/user/login)
if (!StringUtils.isEmpty(username) && "123456".equals(password)) { // 登录成功,就跳转到下一个页面 // 重定向URL return "redirect:/main.html";
2.然后在之前的MyMvcConfig中添加一下映射的路径,让上边的main.html引到我们想要跳转的那个“dashboard”页。
registry.addViewController("/main.html").setViewName("dashboard");
3. 再来用正确的账号密码登录一下,查看我们修改的东西是否生效了,注意看url和页面:
很棒,效果和我们想的基本一样,那么这还没完,一个完整的登录还有其他的问题,比如我们把这个url复制到其他浏览器会是什么样子的?
依然能访问成功,那我们做登录还有卵用,所以这个时候,拦截器的作用就体现出来了。
拦截器
首先,了解一下拦截器的作用,他是用来做登录检查的,也就是没有前边的登录,就不可以访问后边的页面。
如何实现,来看:
1. 先添加一个拦截器,我们新建一个登录的拦截器在component包下,名字就叫 LoginHandlerInterceptor (实现接口HandlerInterceptor),IDEA编译器,我们按ctrl+O,把需要用到的三个接口都拉出来,然后开始编写:
/** * 拦截器,登录检查 */ public class LoginHandlerInterceptor implements HandlerInterceptor { // 目标方法执行之前 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Object user = request.getSession().getAttribute("loginUser"); // 如果获取的request的session中的loginUser参数为空(未登录),就返回登录页,否则放行访问 if (user == null) { // 未登录,给出错误信息, request.setAttribute("msg","无权限请先登录"); // 获取request返回页面到登录页 request.getRequestDispatcher("/index.html").forward(request, response); return false; } else { // 已登录,放行 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 { } }
2. 上边配置的session需要取值才能做判断,那么我们需要在controller中设置这个session值,以让它生效:
3. 之前说过,要让登录有个拦截器的功能,就是除了访问首页我们可以,其他未登录的都拦截下来,所以,需要在MyMvcConfig中添加一个拦截器,让上边的配置都有作用:
// 注册拦截器 @Override public void addInterceptors(InterceptorRegistry registry) { // 添加拦截的请求,并排除几个不拦截的请求 registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**") .excludePathPatterns("/index.html", "/", "/user/login"); }
这样,除了首页的请求意外,其他请求都会被拦截下来,我们再看这样配置以后的效果:
当我们直接访问localhost:8080/main.html时:
这时候,就只能通过拦截器排除的那几个请求来访问和登录后才能正常访问了