最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于SpringBoot實(shí)現(xiàn)Web應(yīng)用的登錄與退出功能

 更新時(shí)間:2024年04月21日 09:32:07   作者:啊Q老師  
登錄與退出功能作為 Web 應(yīng)用中的基礎(chǔ)且重要的組成部分,直接關(guān)系到用戶的安全和隱私保護(hù),所以本文給大家介紹了基于SpringBoot實(shí)現(xiàn)Web應(yīng)用的登錄與退出功能,文中有詳細(xì)的代碼供大家參考,需要的朋友可以參考下

前言

登錄與退出功能作為 Web 應(yīng)用中的基礎(chǔ)且重要的組成部分,直接關(guān)系到用戶的安全和隱私保護(hù)。通過實(shí)現(xiàn)登錄與退出功能,可以對(duì)用戶的身份進(jìn)行驗(yàn)證和授權(quán),確保只有合法的用戶才能訪問特定的資源或執(zhí)行特定的操作。同時(shí),退出功能也為用戶提供了便捷的方式來結(jié)束當(dāng)前會(huì)話,保護(hù)其個(gè)人信息不被他人冒用。在完成 Spring Boot 前五章的學(xué)習(xí)后,下面簡(jiǎn)單介紹使用 Spring Boot 實(shí)現(xiàn)登錄與退出的功能。

實(shí)現(xiàn)登錄功能

案例中選用 Spring Boot 3.0.2 作為整合、Thymeleaf 作為視圖、Spring Data JPA 作為持久層

簡(jiǎn)單示例:

首先,創(chuàng)建新項(xiàng)目 SpringBootWebDemo ,勾選 Web 、MySQL 、ThymeleafJPA 的啟動(dòng)器

在這里插入圖片描述

然后,在 application.properties 全局配置文件中配置數(shù)據(jù)庫連接信息

#數(shù)據(jù)庫連接信息
spring.datasource.username=root
spring.datasource.password=0123
spring.datasource.url=jdbc:mysql://localhost:3306/springbootwebdemo
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# SpringBoot 內(nèi)部使用 SpringData , SpringData 的 JPA 是使用 Hibernate 實(shí)現(xiàn)的
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

接著,創(chuàng)建 Entity 包并在包內(nèi)創(chuàng)建兩個(gè)實(shí)體類 User 和 Address

package cn.edu.SpringBootWebDemo.Entity;

import jakarta.persistence.*;

import java.util.Date;

@Entity
@Table(name = "user")
public class User {
    private int id;
    private String username;
    private String password;
    private Date regDate; // 注冊(cè)日期
    private Address address; // 地址

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Column(name = "reg_date") // 指定字段名
    public Date getRegDate() {
        return regDate;
    }

    public void setRegDate(Date regDate) {
        this.regDate = regDate;
    }

    @ManyToOne // 假設(shè):每一個(gè)用戶對(duì)應(yīng)一個(gè)地址,一個(gè)地址可以對(duì)應(yīng)多個(gè)用戶
    @JoinColumn(name = "address_id") // 一般在多的這邊建立外鍵
    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", regDate=" + regDate +
                ", address=" + address +
                '}';
    }
}
package cn.edu.SpringBootWebDemo.Entity;

import jakarta.persistence.*;

@Entity
@Table(name = "address")
public class Address {
    private int id;
    private String addressInfo; // 地址詳情

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Column(name = "address_info") // 指定字段名
    public String getAddressInfo() {
        return addressInfo;
    }

    public void setAddressInfo(String addressInfo) {
        this.addressInfo = addressInfo;
    }

    @Override
    public String toString() {
        return "Address{" +
                "id=" + id +
                ", addressInfo='" + addressInfo + '\'' +
                '}';
    }
}

隨之,創(chuàng)建 Dao 包并在包內(nèi)創(chuàng)建一個(gè) UserDao 接口,繼承 JpaRepository<實(shí)體類,主鍵類型> ,并且聲明一個(gè)默認(rèn)接口中沒有提供,需要根據(jù)用戶名查詢賬號(hào)的方法

package cn.edu.SpringBootWebDemo.Dao;

import cn.edu.SpringBootWebDemo.Entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserDao extends JpaRepository<User,Integer> {

    // 默認(rèn)接口中沒有提供根據(jù)用戶名查詢賬號(hào)的方法
    public User getByUsername(String username);

}

再創(chuàng)建 Service 包并在包內(nèi)創(chuàng)建一個(gè) UserService 接口,并創(chuàng)建該接口的實(shí)現(xiàn)類 UserServiceImpl

package cn.edu.SpringBootWebDemo.Service;

import cn.edu.SpringBootWebDemo.Entity.User;

public interface UserService {
    public User login(User user);
}
package cn.edu.SpringBootWebDemo.Service;

import cn.edu.SpringBootWebDemo.Dao.UserDao;
import cn.edu.SpringBootWebDemo.Entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service("userService")
public class UserServiceImpl implements UserService{

    @Autowired
    private UserDao userDao;

    @Override
    public User login(User user) {
        // 根據(jù)用戶名查詢有沒有對(duì)應(yīng)的賬號(hào)
        User user1 = userDao.getByUsername(user.getUsername());
        // 判斷是否為空或密碼錯(cuò)誤,登錄失敗返回 null
        if (user1 == null) return null;
        if(!user1.getPassword().equals(user.getPassword())) return null;
        // 返回 User 對(duì)象,登錄成功
        return user1;
    }
}

其次,創(chuàng)建 Controller 包并在包內(nèi)創(chuàng)建一個(gè) UserController 類

package cn.edu.SpringBootWebDemo.Controller;

import cn.edu.SpringBootWebDemo.Entity.User;
import cn.edu.SpringBootWebDemo.Service.UserService;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

@Controller
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/Login.html")
    public String login(HttpSession httpSession){
        // 成功登錄后不能再返回登錄頁面,而是跳轉(zhuǎn)到主頁
        boolean flag = httpSession.getAttribute("loginUser")==null?true:false;
        if (flag){
            return "Login";
        }else {
            return "redirect:/Main.html";
        }
    }

    @GetMapping("/Main.html")
    public String main(){
        return "Main";
    }

    // 判斷登錄
    @PostMapping("/Login.html")
    public String login(User user, HttpSession httpSession, Model model){
        // 控制層——接受頁面的賬號(hào)和密碼。調(diào)用服務(wù)層的 login 方法,判斷登錄是否成功。
        // 成功將返回的 user 對(duì)象保存到 session 的域空間;反之返回一個(gè)錯(cuò)誤提示。
        User user1 = userService.login(user);
        if(user1 != null) {
            // 將返回的 user 對(duì)象保存到 session 的域空間,頁面跳轉(zhuǎn)到主頁中
            httpSession.setAttribute("loginUser",user1);
            return "redirect:/Main.html";
        }else {
            // 登錄失敗,返回錯(cuò)誤提示
            model.addAttribute("loginError","用戶名或密碼錯(cuò)誤!");
            return "Login";
        }
    }
}

最后,在 resources/templates 目錄下創(chuàng)建兩個(gè)頁面 Login.html 和 Main.html ,再啟動(dòng) Spring Boot ,打開瀏覽器輸入 http://localhost:8080/Login.html 并按下回車鍵進(jìn)行進(jìn)行測(cè)試(啟動(dòng) Spring Boot 后,數(shù)據(jù)表會(huì)自動(dòng)生成,但需自行插入一條信息進(jìn)行測(cè)試)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>LoginDemo</title>
</head>
<body>
    <!--  loginError 不為空才顯示錯(cuò)誤提示  -->
    <div style="color: red;" th:text="${loginError}" th:if="${not #strings.isEmpty(loginError)}"></div>

    <form th:action="@{/Login.html}" method="post">
        賬號(hào):<input type="text" name="username" placeholder="請(qǐng)輸入賬號(hào)"> <br>
        密碼:<input type="password" name="password" placeholder="請(qǐng)輸入密碼"> <br>
        <input style="margin-left: 54px;" type="submit" value="登錄">
    </form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>MainDemp</title>
</head>
<body>
    登錄成功!?。?
    主頁
</body>
</html>

結(jié)果如圖:

1.登錄頁面

在這里插入圖片描述

2.輸入賬號(hào)密碼,進(jìn)行登錄

在這里插入圖片描述

3.登錄成功,進(jìn)入主頁

在這里插入圖片描述

4.錯(cuò)誤提示

在這里插入圖片描述

配置攔截器

通常為了確保用戶在訪問需要認(rèn)證的資源之前已經(jīng)登錄,需要在登錄功能中配置攔截器。

簡(jiǎn)單示例:

首先,創(chuàng)建 Web 包并在包內(nèi)創(chuàng)建一個(gè) LoginFilter 類來自定義攔截器

package cn.edu.SpringBootWebDemo.Web;

import cn.edu.SpringBootWebDemo.Entity.User;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.web.servlet.HandlerInterceptor;

public class LoginFilter implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession httpSession = request.getSession();
        // 從 session 的域空間獲取 user 對(duì)象
        User user = (User) httpSession.getAttribute("loginUser");
        if(user != null){
            // 已登錄,放行
            return true;
        }else {
            // 沒有登錄,不能訪問主頁面,出現(xiàn)提示信息
            request.setAttribute("loginError","請(qǐng)登錄后再訪問!");
            request.getRequestDispatcher("/Login.html").forward(request,response);
            return false;
        }
    }
}

然后,創(chuàng)建 Configuration 包并在包內(nèi)創(chuàng)建一個(gè)配置類 LoginFilterConfiguration ,將攔截器存放在配置類中,才能注冊(cè)到 Spring Boot 環(huán)境里

package cn.edu.SpringBootWebDemo.Configuration;

import cn.edu.SpringBootWebDemo.Web.LoginFilter;
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 LoginFilterConfiguration implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注冊(cè)自定義的攔截器,攔截所有請(qǐng)求,排除登錄頁面
        registry.addInterceptor(new LoginFilter())
                .addPathPatterns("/**")
                .excludePathPatterns("/Login.html");

        // 在 Spring MVC 中,還需要排除靜態(tài)資源( *.css 、*.js 、*.jpg 等)攔截
        // 在 Spring Boot 中,已設(shè)置排除,不需再添加
    }
}

最后,啟動(dòng) Spring Boot ,打開瀏覽器輸入 http://localhost:8080/Main.html 并按下回車鍵進(jìn)行進(jìn)行測(cè)試

結(jié)果如圖:

在這里插入圖片描述

實(shí)現(xiàn)退出功能

在成功登錄后,通常用戶被重定向到主頁,而不是返回登錄頁面。同時(shí),提供一個(gè)退出功能讓用戶能夠主動(dòng)注銷并清除會(huì)話信息,也是必要的安全措施。

簡(jiǎn)單示例:

首先,在 Main.html 中重新編寫

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>MainDemo</title>
</head>
<body>
    登錄成功!??!<br>
    <h3>主頁</h3> <br>
    <a th:href="@{/logout.html}" rel="external nofollow" >退出</a>
</body>
</html>

然后,在 UserController 類上添加一個(gè)退出的方法

// 退出
@GetMapping("/logout.html")
public String logout(HttpSession httpSession){
    // 通過 invalidate 方法清空 httpSession 里的內(nèi)容
    httpSession.invalidate();
    return "redirect:/Login.html";
}

最后,啟動(dòng) Spring Boot ,打開瀏覽器輸入 http://localhost:8080/Login.html 并按下回車鍵進(jìn)行進(jìn)行測(cè)試

結(jié)果如圖:

成功登錄后,點(diǎn)擊退出便返回登錄頁面

在這里插入圖片描述

以上就是基于SpringBoot實(shí)現(xiàn)Web應(yīng)用的登錄與退出功能的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot登錄與退出的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java多線程模擬電影售票過程

    Java多線程模擬電影售票過程

    這篇文章主要為大家詳細(xì)介紹了Java多線程模擬電影售票過程,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • HashMap的get()方法的NullPointerException問題

    HashMap的get()方法的NullPointerException問題

    這篇文章主要介紹了HashMap的get()方法的NullPointerException問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • 關(guān)于Idea卡在Resolving Maven dependencies的解決方案

    關(guān)于Idea卡在Resolving Maven dependencies的解決方案

    本文詳細(xì)介紹了關(guān)于Idea卡在Resolving Maven dependencies的解決方案,文中通過圖文結(jié)合的形式給大家介紹的非常詳細(xì),對(duì)大家解決問題有一定的幫助,需要的朋友可以參考下
    2024-02-02
  • java(包括springboot)讀取resources下文件方式實(shí)現(xiàn)

    java(包括springboot)讀取resources下文件方式實(shí)現(xiàn)

    這篇文章主要介紹了java(包括springboot)讀取resources下文件方式實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Maven Repository倉庫的具體使用

    Maven Repository倉庫的具體使用

    本文主要介紹了Maven Repository倉庫的具體使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • 使用RequestBodyAdvice實(shí)現(xiàn)對(duì)Http請(qǐng)求非法字符過濾

    使用RequestBodyAdvice實(shí)現(xiàn)對(duì)Http請(qǐng)求非法字符過濾

    這篇文章主要介紹了使用RequestBodyAdvice實(shí)現(xiàn)對(duì)Http請(qǐng)求非法字符過濾的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • JavaWeb請(qǐng)求轉(zhuǎn)發(fā)和請(qǐng)求包含實(shí)現(xiàn)過程解析

    JavaWeb請(qǐng)求轉(zhuǎn)發(fā)和請(qǐng)求包含實(shí)現(xiàn)過程解析

    這篇文章主要介紹了JavaWeb請(qǐng)求轉(zhuǎn)發(fā)和請(qǐng)求包含實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • java開發(fā)分布式服務(wù)框架Dubbo原理機(jī)制詳解

    java開發(fā)分布式服務(wù)框架Dubbo原理機(jī)制詳解

    這篇文章主要為大家介紹了java開發(fā)分布式服務(wù)框架Dubbo的原理機(jī)制詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-11-11
  • 多線程(多窗口賣票實(shí)例講解)

    多線程(多窗口賣票實(shí)例講解)

    下面小編就為大家?guī)硪黄嗑€程(多窗口賣票實(shí)例講解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • 使用Mybatis接收Integer參數(shù)的問題

    使用Mybatis接收Integer參數(shù)的問題

    這篇文章主要介紹了使用Mybatis接收Integer參數(shù)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03

最新評(píng)論

缙云县| 增城市| 子洲县| 泾川县| 孝义市| 会理县| 稷山县| 班戈县| 利辛县| 揭东县| 新巴尔虎右旗| 利辛县| 华蓥市| 玉林市| 元氏县| 林西县| 高平市| 明水县| 泰州市| 包头市| 大城县| 富蕴县| 绥中县| 偃师市| 西平县| 平顶山市| 阳春市| 汕尾市| 英超| 定襄县| 麻栗坡县| 扶风县| 合川市| 建始县| 天峻县| 关岭| 安仁县| 洛阳市| 金阳县| 泽库县| 商丘市|