22. SpringBoot 实现登录功能 (转发 和 重定向) 和 拦截器功能 【前后端结合 主要学思想和使用】
这里不连接数据库 直接通过控制器判断 和 SpringMVC 拓展实现:
学习目标:
1 . 转发 和 重定向,这里会详细说明;
2. 拦截器的定义 和 注册
3. thymeleaf 的一些绑定(略将 其实直接去取数据即可)
最后的项目结构:
1. 登录功能的实现:

package com.bihu.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpSession; import java.util.Map; @Controller public class userController { /** *首页登录控制器 * @return 然后视图 直接访问 */ @RequestMapping(value = {"/","/index"}) public String login(){ return "index"; } /*** * 登录控制器 * @param username 用户名 * @param password 密码 * @param message 登录失败分发的消息 * @param session Session对象 主要用来传用户名给拦截器 * @return */ @PostMapping("/login") public String login(@RequestParam("username") String username, @RequestParam("password") String password, Map<String,Object> message, HttpSession session){ //判断登录条件【这里不连接数据库】 if((username!=null && username.equals("Admin")) && (password != null && password.equals("123456")) ){ session.setAttribute("loginUsername",username); //设置用户名 表示登录成功 拦截器需要 return "redirect:/main.html"; //防止重复提交!!!但是注意这里重定向不能是url,这个main.html不存在 因为我们的视图在template目录下 ,然而我们在拓展哪里增加了映射跳转!!! } //登录失败那就到登录页面 session.removeAttribute("loginUsername"); //防止BUG 移除用户名 message.put("msg","抱歉,请检查您的账号或密码错误!"); return "index"; } }
里面都有注释,但是为什么重定向是那样的? 因为重定向是直接访问url实现,但我们的视图不是在静态文件夹下的 我们的视图是在 template模板文件夹下面,不能直接 xxxx.html 访问的,
只能通过 返回视图实现访问
所以我们需要返回main.html 这个是不存在的 但为什么会跳转因为我们配置类中 拓展了 SpringMVC的功能:
所以 SpringBoot的重定向功能你懂了没???????
转发是可以直接转的,但是转发也是不能在 template 文件夹下找视图文件,所以你可以这样:
所以这就是转发和重定向,这就是 重定向访问 不在静态文件夹 下面的的视图文件!!!! 但是直接用那就是另一种用法了 这里重点介绍前者。
2.拦截器功能
1.定义自己的拦截器:

package com.bihu.component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class LoginHandlerInterceptor implements HandlerInterceptor { //自定义拦截器进行登录权限 实现HandlerInterceptor类 @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { String username = (String) httpServletRequest.getSession().getAttribute("loginUsername"); if ((username != null) && (!username.isEmpty())){ //判断是否登录 return true; } httpServletRequest.setAttribute("msg","抱歉,请先登录"); //没登录 直接返回登录页面 这里看起来是转发 其实这里是重定向(SpringMVC拓展写了转发) httpServletRequest.getRequestDispatcher("/index.html").forward(httpServletRequest,httpServletResponse); return false; } @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { } }
可以看到里面 主要是 判断 用户名 如果null 或 用户名为空的话 那就转发然后实现重新登录的功能,而且还携带了信息给模板 ,模板也可以直接th:text("${msg}") 获取的 ,可以看到 这里的 index.html 也是不存在的 ,也是通过SpringMVC 拓展功能实现 转发 + 重定向 两个功能。我认为就是这样的 写出来的也和自己想的一样。
2.在配置类中注册自己定义的拦截器 也是SpringMVC 拓展功能 里面的 addInterceptors , 详细看代码:

package com.bihu.config; import com.bihu.component.LoginHandlerInterceptor; import com.bihu.component.MyLocaleResolver; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration public class mConfig extends WebMvcConfigurerAdapter { //添加请求映射 @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/index.html").setViewName("/index"); //登录页面的 充当重定向功能 registry.addViewController("/main.html").setViewName("/dashboard"); //登录成功的 充当重定向功能 } //注册拦截器(自己写的) @Override public void addInterceptors(InterceptorRegistry registry) { //静态资源就不用配置了 静态资源SpringBoot 已自动配置好了 registry.addInterceptor(new LoginHandlerInterceptor()) .addPathPatterns("/**") //拦截全部 .excludePathPatterns("/index.html","/","/login"); //排除登录功能请求 } //添加自定义区域代码解析器【国际化】 @Bean public LocaleResolver localeResolver(){ return new MyLocaleResolver(); } }
总结:为什么要写拦截器? 正是因为 如果配,我们那些 比如 登录成功的页面 不就直接可以访问了吗 那登录毫无没意义。
比如:
http://localhost:8080/main.html
main.index 是不存在的 ,正式因为重定向 我们才可以再次跳转到 dashboard这个视图。
⭐ 静态资源在SpringBoot 中 是不用配置的。 静态资源SpringBoot 已自动配置好了
下面是模板代码 登录页视图 注意看下那些thymeleaf表达式吧:

<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" content=""> <meta name="author" content=""> <title>Signin Template for Bootstrap</title> <!-- Bootstrap core CSS --> <link href="asserts/css/bootstrap.min.css" rel="stylesheet" th:href="@{/webjars/bootstrap/4.0.0/dist/css/bootstrap.css}" /> <!-- Custom styles for this template --> <link href="asserts/css/signin.css" rel="stylesheet" th:href="@{/asserts/css/signin.css}" /> </head> <body class="text-center"> <form class="form-signin" th:action="@{/login}" method="post"> <img class="mb-4" src="asserts/img/bootstrap-solid.svg" alt="" width="72" height="72"> <h1 class="h3 mb-3 font-weight-normal" th:text="#{login.title}">Please sign in</h1> <p style="color: red" th:text="${msg}" ></p> <label class="sr-only" >Username</label> <input type="text" name="username" class="form-control" th:placeholder="#{login.username}" placeholder="Username" required="" autofocus=""> <label class="sr-only" th:text="#{login.passwprd}" >Password</label> <input type="password" name="password" class="form-control" th:placeholder="#{login.passwprd}" placeholder="Password" required=""> <div class="checkbox mb-3"> <label> <input type="checkbox" value="remember-me"> [[#{login.Remember}]] </label> </div> <button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.sign}" >Sign in</button> <p class="mt-5 mb-3 text-muted">© 2017-2018</p> <a class="btn btn-sm" th:href="@{/?l=zh_CN}">中文</a> <a class="btn btn-sm" th:href="@{/?l=en_US}">English</a> </form> </body> </html>
本文来自博客园,作者:咸瑜,转载请注明原文链接:https://www.cnblogs.com/bi-hu/p/15130353.html