在 pom.xml 文件当中,导入相关的 jar
包文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.rainbowsea</groupId> <artifactId>springboot_usersys</artifactId> <version>1.0-SNAPSHOT</version> <!-- 导入SpringBoot 父工程-规定写法--> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.3</version> </parent> <!-- 导入web项目场景启动器:会自动导入和web开发相关的jar包所有依赖【库/jar】--> <!-- 后面还会在说明spring-boot-starter-web 到底引入哪些相关依赖--> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--引入lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!-- 引入 thymeleaf-start ,项目会自动完成配置,--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- 引入 lombok 插件 --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> </project> |
编写相关项目的启动场景。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package com.rainbowsea.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication // 项目启动标志 public class Application { public static void main(String[] args) { SpringApplication.run(Application.class,args); } } |
对应的 Bean 类
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package com.rainbowsea.springboot.bean; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor // 无参数 public class Admin { private String name; private String password; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package com.rainbowsea.springboot.bean; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor // 无参数 @AllArgsConstructor // 全参数 public class User { private Integer id; private String name; private String password; private Integer age; private String email; } |
编写相关 thymeleaf 视图,HTML文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>管理后台</title> </head> <body> <a href="#">返回管理界面</a> <a href="#">安全推出</a> <hr> <div style="text-align: center"> <h1>管理员</h1> <table border="1px" cellspacing="0" bordercolor="green" style="text-align: center"> <tr bgcolor="pink"> <td>id</td> <td>name</td> <td>pwd</td> <td>email</td> <td>age</td> </tr> <tr bgcolor="#7fffd4" style="text-align: center" th:each="user:${users}"> <td th:text="${user.id}"></td> <td th:text="${user.name}"></td> <td th:text="${user.password}"></td> <td th:text="${user.email}"></td> <td th:text="${user.age}"></td> </tr> </table> </div> </body> </html> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>login</title> </head> <body> <div style="text-align: center"> <h1>用户登录</h1> <form action="#" th:action="@{/login}" method="post"> <label style="color: red" th:text="${msg}"></label><br> 用户名: <input type="text" style="width: 150px" name="name"><br> 密码: <input type="password" style="width: 150px" name="password"><br> <input type="submit" value="登录"><br> <input type="reset" value="重新填写"><br> </form> </div> </body> </html> |
相关的 controller 控制器,处理请求内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
package com.rainbowsea.springboot.controller; import com.rainbowsea.springboot.bean.Admin; import com.rainbowsea.springboot.bean.User; import com.sun.org.apache.xpath.internal.operations.Mod; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import javax.jws.WebParam; import javax.servlet.http.HttpSession; import java.util.ArrayList; @Controller public class AdminController { @PostMapping("/login") public String login(Admin admin, HttpSession session, Model model) { // 验证用户是否合法 if(StringUtils.hasText(admin.getName()) && "666".equals(admin.getPassword())) { // 将登录用户保险到 session会话域当中 session.setAttribute("loginAdmin",admin); // 合法,重定向到manage.html // 请小伙伴回忆,Java web ,不使用请求转发是防止刷新页面会重复提交 // 这里老师为什么写的是 manage.html,因为这样可以更加明确的表示到哪个页面 // manage.html 表示要去找方法的映射路径为: manage.html return "redirect:/manage.html"; } else { // 不合法,就重新登录,请求转发 model.addAttribute("msg","账号/用户错误"); return "adminLogin"; // 视图解析 } } // 处理用户的请求到 manage.html // 是重定向——>get @GetMapping("/manage.html") public String mainPage(Model model,HttpSession session){ // 可以这里集合~模板数据,放入到request域中,并显示 ArrayList<User> users = new ArrayList<>(); users.add(new User(1,"关羽","666",28,"gy@ohu.com")); users.add(new User(2,"关羽","666",28,"gy@ohu.com")); users.add(new User(3,"关羽","666",28,"gy@ohu.com")); users.add(new User(4,"关羽","666",28,"gy@ohu.com")); users.add(new User(5,"关羽","666",28,"gy@ohu.com")); model.addAttribute("users",users); // 放入到请求域当中 return "manage"; // 视图解析器 // 拦截器处理 // 获取到 session会话域当中的信息,判断用户是否登录过,进行一个过滤 /*Object loginAdmin = session.getAttribute("loginAdmin"); if(null != loginAdmin) { // 说明成功登录过 // 可以这里集合~模板数据,放入到request域中,并显示 ArrayList<User> users = new ArrayList<>(); users.add(new User(1,"关羽","666",28,"gy@ohu.com")); users.add(new User(2,"关羽","666",28,"gy@ohu.com")); users.add(new User(3,"关羽","666",28,"gy@ohu.com")); users.add(new User(4,"关羽","666",28,"gy@ohu.com")); users.add(new User(5,"关羽","666",28,"gy@ohu.com")); model.addAttribute("users",users); // 放入到请求域当中 return "manage"; // 视图解析器 } else { // 说明没有登录过, // 这里就返回登录页,并给出提示 model.addAttribute("msg","你没有登录/请登录"); // 请求域 return "adminLogin"; // 请求转发到 adminLogin.html视图解析 }*/ } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
package com.rainbowsea.springboot.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @Controller public class IndexController { // 编写方法,转发到登录页面 /* 解释: 1.因为我们引入了 starter-thymeleaf 2.这里就会直接使用视图解析到thymeleaf下的模板文件admin */ @GetMapping(value = {"/","/login"}) public String login(){ return "adminLogin"; } } |
演示:拦截器:这里我们演示,登录页面的拦截:
- 当用户没有登录过的时候,不可以访问后面的内容
- 当用户登录过了,就可以访问后面的内容了。
首先我们需要定义一个类,并且该类要实现 implements HandlerInterceptor 接口,同时重写其中的 :preHandle( ),postHandle( ),afterCompletion( )
的三个方法。根据业务拦截的需要,在这个三个方法中,编写,拦截的业务处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
package com.rainbowsea.springboot.interceptor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @Slf4j public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 为了让大家看到访问的URI String requestURI = request.getRequestURI(); String requestURL = request.getRequestURL().toString(); log.info("preHandle 拦截到的请求URI={}", requestURI); log.info("preHandle 拦截到的请求URL={}", requestURL); // 进行登录的校验 HttpSession session = request.getSession(); Object loginAdmin = session.getAttribute("loginAdmin"); if (null != loginAdmin) { // 说明该用户已经成功登录 // 返回 true 就是放行 return true; } else { // 拦截,重新返回到登录页面 request.setAttribute("msg", "你没有登录/请登录~~~"); // 注意:因为这里我们只有一个内容被拦截了,而且该内容的 uri路径就是我们要跳转进入的路径 request.getRequestDispatcher("/").forward(request, response); // 重定向 return false; // 拦截了,不放行 } } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { log.info("postHandle执行了..."); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { log.info("afterCompletion执行了..."); } } // HandlerInterceptor |
定义一个配置类,在配置类当中,编写我们要拦截哪些请求路径映射,放行哪些请求路径的映射。
注意:
- 添加上:@Configuration 注解 // 标注是配置类
- 该类要实现:implements WebMvcConfigurer 类
- 重写其中的:public void addInterceptors(InterceptorRegistry registry) 方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
package com.rainbowsea.springboot.config; import com.rainbowsea.springboot.interceptor.LoginInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration // 标注是配置类,配置拦截器, public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { // 注册自定义拦截器LoginInterceptor registry.addInterceptor(new LoginInterceptor()) .addPathPatterns("/**") // 拦截所有的请求 .excludePathPatterns("/","/login","/images/**"); // 还要放行视图的内容,因为上面是 // 拦截所有,注意不要: templates ,因为sprinboot的默认配置,就是以templates为根路径往下找的 // 所以添加就错了,就成了 /templates/templates/images/**了。 } } |
注意点:
12345678910 @Overridepublic void addInterceptors(InterceptorRegistry registry) {// 注册自定义拦截器LoginInterceptorregistry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**") // 拦截所有的请求.excludePathPatterns("/","/login","/images/**"); // 还要放行视图的内容,因为上面是// 拦截所有,注意不要: templates ,因为sprinboot的默认配置,就是以templates为根路径往下找的// 所以添加就错了,就成了 /templates/templates/images/**了。}
123 // 还要放行视图的内容,因为上面是// 拦截所有,注意不要: templates ,因为sprinboot的默认配置,就是以templates为根路径往下找的// 所以添加就错了,就成了 /templates/templates/images/**了。注意:配置了拦截器的话,图片之类的一些静态资源的访问以及一些文件上传下载,也是要注意放行的,已经视图解析器也是放行的,要放行视图的内容,因为上面是
addPathPatterns("/**") // 拦截所有的请求
拦截所有,注意不要: templates ,因为sprinboot的默认配置,就是以templates为根路径往下找的,所以再添加 templates 就错了,就成了 /templates/templates/images 了。简单的就是:记住注意好 Spring Boot的根路径是从哪里开始的,以哪里为根路径的,可能有多个标准/参照路径。
基于第一种方式修改,webconfig 配置类即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
package com.rainbowsea.springboot.config; import com.rainbowsea.springboot.interceptor.LoginInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration // 标注配置类,配置拦截器 public class WebConfig { @Bean public WebMvcConfigurer webMvcConfigurer() { return new WebMvcConfigurer() { @Override public void addInterceptors(InterceptorRegistry registry) { System.out.println("addInterceptors~~~"); // 注册拦截器 registry.addInterceptor(new LoginInterceptor()) .addPathPatterns("/**") .excludePathPatterns("/","/login","/images/**"); } }; } } |
1.URI 和 URL 的区别
URI = Universal Resource Identifier
URL = Universal Resource Locator
1 2 3 |
// 为了让大家看到访问的URI String requestURI = request.getRequestURI(); // preHandle 拦截到的请求URI=/manage.html String requestURL = request.getRequestURL().toString(); // preHandle 拦截到的请求URL=http://localhost:8080/manage.html |
1 2 3 |
// 还要放行视图的内容,因为上面是 // 拦截所有,注意不要: templates ,因为sprinboot的默认配置,就是以templates为根路径往下找的 // 所以添加就错了,就成了 /templates/templates/images/**了。 |
注意:配置了拦截器的话,图片之类的一些静态资源的访问以及一些文件上传下载,也是要注意放行的,已经视图解析器也是放行的,要放行视图的内容,因为上面是addPathPatterns("/**") // 拦截所有的请求
拦截所有,注意不要: templates ,因为sprinboot的默认配置,就是以templates为根路径往下找的,所以再添加 templates 就错了,就成了 /templates/templates/images 了。
简单的就是:记住注意好 Spring Boot的根路径是从哪里开始的,以哪里为根路径的,可能有多个标准/参照路径。
“在这个最后的篇章中,我要表达我对每一位读者的感激之情。你们的关注和回复是我创作的动力源泉,我从你们身上吸取了无尽的灵感与勇气。我会将你们的鼓励留在心底,继续在其他的领域奋斗。感谢你们,我们总会在某个时刻再次相遇。”
from:https://www.cnblogs.com/TheMagicalRainbowSea/p/18414183