本文記錄用SpringBoot 實現簡單的用戶登錄過程,對於初步入門的我來說遇到了很多的困難,所以在實現登錄後特寫此篇文章。描述我在實現過程中遇到的問題和疑惑,也算是自己的學習筆記吧!!
開發環境:
- IDE:JetBrains Intelij IDEA
- Java:JavaSE13
- SpringBoot + xadmin + Layui +Mybatis + MySQL
詳細過程:
文件目錄:
實現用戶登錄功能用到的目錄已經標出:
- 【domain】目錄主要用於實體(Entity)與數據訪問層(Repository)控制
- 【service 】層主要是業務類代碼
- 【controller 】負責頁面訪問控制
- 【dao】數據庫訪問層
- 【entity】實體層(這裏沒有)
設置和連接數據庫:
建立數據庫
在Navicat中建立一個數據庫,並建立一張用戶表(用來存儲要登錄的用戶)
用戶登錄主要用到下面這張user表,這裏事先輸入了用戶名和密碼。
設置application.properties文件
然後,打開SpringBoot項目的application.properties文件,配置如下信息:
# 數據庫的連接驅動
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 連接數據庫的地址,注意端口和要連接的數據庫名,後面設置時區,不然可能會報錯
spring.datasource.url=jdbc:mysql://localhost:3306/database-manager?serverTimezone=UTC
# 連接的賬號和密碼,根據自己情況
spring.datasource.username=root
spring.datasource.password=123456
# 下面關於mybatis的要設置,不然會報錯,讀取不了數據庫數據。
# mapper xml文件路徑
mybatis.mapper-locations=classpath:mapper/*.xml
# 實體類別名
mybatis.type-aliases-package=pinksmile.database.domin
# 開啓駝峯命名
mybatis.configuration.map-underscore-to-camel-case=true
# 將日誌輸出到控制檯
mybatis.configuration.logImpl=org.apache.ibatis.logging.stdout.StdOutImpl
# 這個開發配置爲false,避免改了模板還要重啓服務器
spring.thymeleaf.cache=false
然後,用IDEA連接數據庫:
使用Mybatis操作數據庫
配置數據庫數據操作UserMapper.xml文件:注意與dao層和domain層關聯。
需要注意的地方下面已經標出(網上有文章介紹):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--author PinkSmile 用戶表-->
<mapper namespace="pinksmile.database.dao.UserDao">
<resultMap id="UserMap" type="pinksmile.database.domain.User">
<result column="id" javaType="Integer" jdbcType="INTEGER" property="id"/>
<result column="nickname" javaType="String" jdbcType="VARCHAR" property="nickname"/>
<result column="username" javaType="String" jdbcType="VARCHAR" property="username"/>
<result column="password" javaType="String" jdbcType="VARCHAR" property="password"/>
<result column="permission" javaType="String" jdbcType="VARCHAR" property="permission"/>
<result column="role" javaType="String" jdbcType="VARCHAR" property="role"/>
</resultMap>
<!--通過用戶名和密碼從表中獲得用戶-->
<select id="login" resultType="pinksmile.database.domain.User">
select * from user where username = #{username} and password = #{password}
</select>
<!--通過用戶id獲得用戶角色-->
<select id="getUserRoleByID" resultType="String">
select role from user where id = #{userId}
</select>
</mapper>
至此,關於數據庫的部分已經配置完成。下面寫代碼部分。
準備頁面:
templates目錄下:
- login.html 登錄頁面
- index.html 登錄後普通用戶跳轉的頁面
- manage.html 登錄後管理員跳轉的頁面
各層文件及作用
首先是【domain】中的User.java,用作數據庫表的映射,描述數據庫中表的信息:
該文件要注意的是下載 lombok 依賴,使用IDEA的拓展插件即可完成,方法可參考網上。
package pinksmile.database.domain;
import lombok.Data;
/**
* 登錄的用戶表
* @author PinkSmile
*/
@Data
public class User {
/**
* 數據庫用戶標的字段
* 保證字段和數據類型一致
*/
private Integer id;
private String nickname;
private String username;
private String password;
private String permission;
private String role;
}
【dao】層數據庫接口:
該層的函數接口和前面配置UserMapper.xml文件有關,此文件是提供接口,而那個配置文件是實現該接口的功能。
package pinksmile.database.dao;
import org.springframework.stereotype.Repository;
import pinksmile.database.domain.User;
@Repository // 這是mybatis操作的數據庫
public interface UserDao {
// 根據用戶名和密碼獲得用戶信息
User login(String username, String password);
// 根據用戶 id 獲取用戶角色
String getUserRoleByID(Integer userId);
}
【service】業務邏輯編寫
在初始化數據庫環境,定義數據庫訪問接口後,下面就是業務邏輯的編寫。
package pinksmile.database.service;
import org.springframework.data.relational.core.sql.In;
import pinksmile.database.dao.UserDao;
import pinksmile.database.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
private UserDao userDao;
// 根據用戶名和密碼登錄
public User login(String username, String password) {
return userDao.login(username, password);
}
// 通過用戶ID得到用戶角色
public String getUserRoleByID(Integer userId) {return userDao.getUserRoleByID(userId);}
}
【controller】負責頁面訪問控制
該層是最麻煩的一層,負責頁面的跳轉和頁面的各種活動。
首先是登錄頁面控制
注意:區分網址和網站頁面的使用,一開始我都沒搞清楚。每一個頁面都對應一個網址。
業務邏輯:
- 輸入網址
http://localhost:8080/login
進入的是登錄頁面,也就是我們寫的login.html前端頁面。 - 如果已經登錄,就重定向跳轉到管理界面
http://localhost:8080/manage
,根據不同的用戶角色跳轉到不同界面 - 如果沒有登錄,就返回登錄頁面。
- 在登錄是否成功時,失敗頁面的網址爲
http://localhost:8080/manage/verification
,但顯示的頁面仍然是登錄頁面。 - 如果登錄判斷成功,就跳轉到管理頁面。
BackManage.java
實現功能:
- 管理頁面和網址的映射,對登錄後的頁面進行跳轉
package pinksmile.database.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import pinksmile.database.domain.User;
import pinksmile.database.service.UserService;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@Controller
public class BackManage {
@Autowired
UserService userService;
/**
* 後臺管理頁面數據準備接口
* @param request 用於獲取Session來判斷是否登錄
* @return 返回模板頁面
*/
@GetMapping("/manage") // 管理頁面網址
public String manage(HttpServletRequest request){
HttpSession session=request.getSession(); // 獲取登錄信息
Object obj = session.getAttribute("user");
// 沒有登錄,返回登錄頁面
if(obj == null){ // 登錄信息爲 null,表示沒有登錄
return "redirect:/login";
}
User loginUser = (User) obj; // 強制轉換成 User
Integer userId = loginUser.getId(); // 獲得登錄用戶的 id
String role = userService.getUserRoleByID(userId); // 通過登錄用戶的 id 得到用戶的角色
// 如果是用戶登錄,返回用戶界面
if (role.equals("user")){
return "index";
}
// 如果是管理員登錄就返回管理頁面
return "manage";
}
@GetMapping("/welcome")
public String toWelcome() {return "welcome";}
}
Login.java:
實現功能:
- 從數據庫獲取密碼進行登錄
- 每到達登錄頁面就判斷是否短時間內已經登陸過,登陸過就直接跳轉到頁面
package pinksmile.database.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import pinksmile.database.domain.User;
import pinksmile.database.service.UserService;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@Controller
public class Login {
@Autowired
UserService userService;
/**
* 用於返回登錄頁面
* @param request 判斷是否已經登錄,已經登錄就直接跳轉
* @return 返回登錄頁面模板
*/
@GetMapping("/login") // 登錄頁面網址
public String login(HttpServletRequest request) {
HttpSession session = request.getSession(); // 獲取用戶登錄信息
// 如果已經登錄,則重定向直接跳轉到判斷界面
if (session.getAttribute("user") != null) {
return "redirect:/manage";
}
// 如果沒有登錄信息,則直接返回登錄頁面
return "login";
}
/**
* 用於驗證賬號和密碼是否正確
*
* @param username 賬號信息
* @param password 密碼信息
* @param request 用於獲取Session
* @return 登錄成功跳轉管理界面,失敗返回錯誤信息到登錄頁面
*/
@PostMapping("/manage/verification") // 失敗錯誤信息頁面網址
public String verification(@RequestParam("username") String username,
@RequestParam("password") String password,
HttpServletRequest request) {
if (username.equals("") || password.equals("")) { // 密碼爲空,重新登錄
return "login";
} else {
User user = userService.login(username, password); // 從數據庫中獲得與輸入相同的用戶
if (user == null) { // 沒有該用戶
return "login";
}
// 創建 session
HttpSession session = request.getSession();
session.setAttribute("user", user);
}
return "redirect:/manage"; // 登錄成功進行頁面選擇跳轉
}
}
運行結果:
普通用戶登錄到後臺管理頁面:
已經登錄後,再登錄直接重定向到管理頁面: