文章目录
- 在未登录的情况下无法直接通过URL打开登录状态才能访问的页面
项目结构
准备:完成登录功能和用户信息展示功能
创建项目SpringMvcDemo2021
登录页面login.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org/">
<head>
<meta charset="UTF-8">
<title>用户登录</title>
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="col-6 m-auto" style="margin-top:30px!important;">
<div class="text-center">
</div>
<div class="border border-info bg-light p-2" style="border-radius: 5px">
<form action="/login" method="post">
<h3 class="text-center">用户登录</h3>
<div class="mt-1">
<input type="text" id="username" name="username" class="form-control" placeholder="输入用户名" required autofocus>
</div>
<div class="mt-1">
<input type="password" id="password" name="password" class="form-control" placeholder="输入密码" required>
</div>
<div class="checkbox text-center">
<label>
<input class="form-check-input text-center" type="checkbox" id="remember-me">记住我
</label>
</div>
<div>
<button class="btn btn-lg btn-primary btn-block" id="login" type="submit">登录</button>
</div>
</form>
</div>
</div>
</body>
</html>
登录成功页面success.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org/">
<head>
<meta charset="UTF-8">
<title>登录成功</title>
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="col-6 text-center m-auto border-info border p-3 bg-light" style="margin-top:50px!important;">
<p th:text="${loginMsg}" class="text-success"></p>
<p><a th:href="@{/allUsers}">显示所有用户信息</a></p>
</div>
</body>
</html>
登录失败页面failure.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org/">
<head>
<meta charset="UTF-8">
<title>登录失败</title>
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="col-6 text-center m-auto border-warning border p-3 bg-light" style="margin-top:50px!important;">
<p th:text="${loginMsg}" class="text-danger"></p>
</div>
</body>
</html>
用户信息页面allUsers.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org/">
<head>
<meta charset="UTF-8">
<title>用户信息</title>
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="col-sm-12 col-md-8 col-xl-4 text-center m-auto border-warning border bg-light"
style="margin-top:20px!important;">
<p class="text-success h4">查询到的用户信息</p>
<table class="table table-hover">
<tr class="row">
<th class="col-sm-3 col-md-3 col-xl-3 text-center">编号</th>
<th class="col-sm-3 col-md-3 col-xl-3 text-center">姓名</th>
<th class="col-sm-3 col-md-3 col-xl-3 text-center">性别</th>
<th class="col-sm-3 col-md-3 col-xl-3 text-center">年龄</th>
</tr>
<tr class="row " th:if="${users} ne null" th:each="user:${users}">
<td class="col-sm-3 col-md-3 col-xl-3 text-center" th:text="${user.id}"></td>
<td class="col-sm-3 col-md-3 col-xl-3 text-center" th:text="${user.name}"></td>
<td class="col-sm-3 col-md-3 col-xl-3 text-center" th:text="${user.gender}"></td>
<td class="col-sm-3 col-md-3 col-xl-3 text-center" th:text="${user.age}"></td>
</tr>
</table>
</div>
</body>
</html>
登录控制器LoginController.java
package net.lj.lesson11.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import javax.servlet.http.HttpServletRequest;
import java.util.Calendar;
/**
* 登录控制器
*/
@Controller
public class LoginController {
/**
* 通过请求“toLoginPage”跳转到templates目录下的
* login页面,并把当前年份数据保存到模型对象中
*/
@GetMapping("/toLoginPage")
public String toLoginPage(Model model) {
model.addAttribute("currentYear", Calendar.getInstance().get(Calendar.YEAR));
return "login"; // 返回逻辑页面视图名称
}
@PostMapping("login")
public String login(HttpServletRequest request, Model model) {
// 获取表单提交的用户名与密码
String username = request.getParameter("username");
String password = request.getParameter("password");
// 判断用户是否登录成功(假设合法用户名为howard,密码为903213)
if (username.equals("admin") && password.equals("123456")) {
model.addAttribute("loginMsg", "恭喜,用户登录成功~");
//将登录用户信息保存在会话里(实际开发中保存的用户对象)
request.getSession().setAttribute("user",username);
return "success";
} else {
model.addAttribute("loginMsg", "遗憾,用户登录失败~");
return "failure";
}
}
}
用户实体类User
package net.lj.lesson11.bean;
/**
* 用户实体类
*/
public class User {
private Integer id;
private String name;
private String gender;
private Integer age;
public User() {
}
public User(Integer id, String name, String gender, Integer age) {
this.id = id;
this.name = name;
this.gender = gender;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", gender='" + gender + '\'' +
", age=" + age +
'}';
}
}
用户控制器UserController.java
package net.lj.lesson11.controller;
import net.lj.lesson11.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
/**
* 用户控制器
*/
@Controller
public class UserController {
@RequestMapping("/allUsers")
public String allUsers(HttpServletRequest request, Model model) {
model.addAttribute("users", getUsers());
return "allUsers"; // 模板页面文件名
}
/**
* @return 用户列表
*/
private List<User> getUsers() {
List<User> users = new ArrayList<>();
users.add(new User(1, "李红玉", "女", 20));
users.add(new User(2, "肖雨涵", "男", 18));
users.add(new User(3, "唐忠刚", "男", 19));
users.add(new User(4, "郑小红", "女", 18));
users.add(new User(5, "陆文君", "女", 19));
return users;
}
}
效果
- 此时的页面可以直接通过URL访问
一、尝试使用视图跳转界面
在config子包中创建自定义配置类MyMvcConfig
- 实现WebMvcConfigurer接口,addViewControllers方法
package net.lj.lesson11.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 自定义配置类
*/
@Configuration //配置类
public class MyMvcConfig implements WebMvcConfigurer {
/**
*添加视图控制器
* @param registry
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// 当通过login.html访问时,直接跳转到login视图对应的页面,即login.html页面
registry.addViewController("login.html").setViewName("login");
}
}
效果
二、编写登录拦截器,限制非登录用户通过URL直接访问用户信息
1.在interceptor子包中创建自定义拦截器MyInterceptor
- 非登录用户直接使用URL访问的情况强制转到登录页面
package net.lj.lesson11.interceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 自定义拦截器
*/
@Component
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
String user = (String) request.getSession().getAttribute("user");
if (user == null) {//表明是非登录用户
response.sendRedirect("toLoginPage");//转向登录页面
}
return true;
}
}
2.在自定义配置类中注入拦截器,编写拦截规则
//注入自定义拦截器
@Autowired
private MyInterceptor interceptor;
//添加拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
//拦截所有路径,除login.html、toLoginPage、login外
registry.addInterceptor(interceptor).addPathPatterns("/**")
.excludePathPatterns("login.html", "/toLoginPage", "/login");
}