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

SpringBoot連接Microsoft SQL Server實現(xiàn)登錄驗證

 更新時間:2025年05月28日 10:20:33   作者:mr.Darker  
本文主要介紹了SpringBoot連接Microsoft SQL Server實現(xiàn)登錄驗證,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

這篇文章將非常系統(tǒng)地講解如何使用 Spring Boot 結(jié)合 Microsoft SQL Server 2019 完成一個完整的登錄驗證系統(tǒng),包括數(shù)據(jù)庫連接問題、SSL證書錯誤處理、CORS跨域詳細(xì)解釋和解決方案。

適合需要前后端聯(lián)調(diào)、單獨(dú)部署數(shù)據(jù)庫、獨(dú)立登錄服務(wù)的場景。

一、環(huán)境準(zhǔn)備

  • 開發(fā)工具:IDEA 2025.1
  • Spring Boot 版本:3.4.3
  • SQL Server 版本:Microsoft SQL Server 2019
  • 瀏覽器:Chrome/Edge

技術(shù)選型

  • Spring Boot Web
  • JDBC 數(shù)據(jù)庫連接
  • HTML + JavaScript 作為前端

項目結(jié)構(gòu)建議

BoounionLoginBackend/
├── src/
│   └── main/
│       ├── java/com/example/boounion/
│       │   ├── controller/LoginController.java
│       │   ├── model/User.java
│       │   ├── service/UserService.java
│       │   └── BoounionLoginBackendApplication.java
│       └── resources/
│			└── static/index.html
│           └── application.properties
├── pom.xml

二、數(shù)據(jù)庫配置詳解(application.properties)

spring.datasource.url=jdbc:sqlserver://localhost:1433;databaseName=BoounionDB;encrypt=true;trustServerCertificate=true
spring.datasource.username=sa
spring.datasource.password=bl123456
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.jpa.hibernate.ddl-auto=none
server.port=8080

重點(diǎn)解釋:

  • encrypt=true :SQL Server 2019 默認(rèn)要求連接加密。如果不加,會連接失敗。
  • trustServerCertificate=true :如果你沒有配置 SSL 證書,可以加上此參數(shù),忽略證書校驗,避免出現(xiàn) PKIX path building failed 錯誤。
  • server.port=8080 :設(shè)置后端啟動端口為8080,確保和前端訪問一致。

連接 SQL Server 常見錯誤總結(jié):

錯誤提示原因解決方法
TCP 1433端口連接失敗SQL Server未開啟TCP/IP配置SQL Server網(wǎng)絡(luò)協(xié)議,啟用TCP/IP
SSL 連接失敗 PKIX Error缺少受信任證書配置 encrypt=true 且 trustServerCertificate=true
登錄失敗用戶名密碼錯誤確認(rèn)賬號密碼正確且允許SQL登錄

遇到的錯誤是典型的 SSL 證書驗證失敗,錯誤信息如下:

驅(qū)動程序無法通過使用 SSL 與 SQL Server 建立安全連接。
錯誤: PKIX path building failed: unable to find valid certification path

三、前端登錄界面(index.html)

頁面結(jié)構(gòu):

<input type="text" id="username" placeholder="用戶名">
<input type="password" id="password" placeholder="密碼">
<button onclick="login()">登錄</button>

美化 CSS 省略,重要的是 登錄函數(shù)邏輯

登錄邏輯 JavaScript:

function login() {
  const username = document.getElementById("username").value;
  const password = document.getElementById("password").value;

  fetch("/api/login", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ username, password })
  })
  .then(response => response.json().then(data => ({ status: response.status, body: data })))
  .then(({ status, body }) => {
    if (status === 200 && body.status === "success") {
      window.location.href = body.redirectUrl;
    } else {
      alert(body.message || "登錄失敗");
    }
  })
  .catch(() => alert("請求失敗,請檢查網(wǎng)絡(luò)"));
}

特點(diǎn):

  • 使用 fetch() 發(fā)送 POST 請求,提交 JSON 格式用戶名和密碼。
  • 登錄成功后,前端通過 window.location.href 跳轉(zhuǎn)。
  • 登錄失敗,使用 alert 彈窗提示用戶。
  • 完全符合現(xiàn)代前后端分離開發(fā)方式。

四、后端登錄接口(LoginController.java)

核心邏輯:

@PostMapping("/login")
public ResponseEntity<Map<String, Object>> login(@RequestBody User user) {
    String result = userService.login(user);
    Map<String, Object> response = new HashMap<>();

    switch (result) {
        case "登錄成功":
            response.put("status", "success");
            response.put("redirectUrl", "https://www.baidu.com/s?wd=csdn");
            return ResponseEntity.ok(response);
        case "密碼錯誤":
            response.put("status", "error");
            response.put("message", "密碼錯誤");
            return ResponseEntity.status(401).body(response);
        case "用戶不存在":
            response.put("status", "error");
            response.put("message", "用戶不存在");
            return ResponseEntity.status(404).body(response);
        default:
            response.put("status", "error");
            response.put("message", "服務(wù)器異常");
            return ResponseEntity.status(500).body(response);
    }
}

亮點(diǎn)說明:

  • 使用 Map 封裝返回 JSON,靈活可擴(kuò)展。
  • 成功返回 200 狀態(tài),帶 redirectUrl,由前端跳轉(zhuǎn)。
  • 失敗返回具體的 401/404/500 狀態(tài)碼,便于前端判斷并提示。

? 保證登錄接口符合 RESTful API 設(shè)計規(guī)范。

五、數(shù)據(jù)庫驗證邏輯(UserService.java)

簡單查詢用戶密碼:

try (Connection conn = DriverManager.getConnection(dbUrl, dbUser, dbPassword)) {
    String sql = "SELECT password FROM Users WHERE username = ?";
    try (PreparedStatement stmt = conn.prepareStatement(sql)) {
        stmt.setString(1, user.getUsername());
        try (ResultSet rs = stmt.executeQuery()) {
            if (!rs.next()) return "用戶不存在";
            if (!rs.getString("password").equals(user.getPassword())) return "密碼錯誤";
            return "登錄成功";
        }
    }
} catch (SQLException e) {
    e.printStackTrace();
    return "數(shù)據(jù)庫錯誤";
}

安全設(shè)計要點(diǎn):

  • 使用 PreparedStatement,防止 SQL 注入攻擊。
  • 明文密碼對比(后期建議增加加密如 BCrypt)。
  • 連接和關(guān)閉資源使用 try-with-resources,避免泄漏。

六、跨域 CORS 問題詳細(xì)解決

現(xiàn)象

前端 fetch 請求接口時報錯:

Access to fetch at ‘http://localhost:8080/api/login’ from origin ‘http://localhost:5500’ has been blocked by CORS policy.

在這里插入圖片描述

原因

瀏覽器安全策略,跨域請求被攔截。

完整解決方案:

1. 配置全局允許跨域

創(chuàng)建 WebConfig.java

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("http://localhost:5500")
                .allowedMethods("GET", "POST")
                .allowCredentials(true);
    }
}
  • allowedOrigins 指定你的前端地址(可以是 IP、本地域名)。
  • allowedMethods 指定支持的方法,如 POST、GET。
  • allowCredentials(true) 允許帶上 cookie(如果未來需要)。

2. 單接口上臨時添加 @CrossOrigin

如果你只想允許登錄接口跨域:

@CrossOrigin(origins = "http://localhost:5500")
@PostMapping("/login")

? 推薦使用全局配置統(tǒng)一處理,維護(hù)簡單。

七、總結(jié)

  • 數(shù)據(jù)庫連接重點(diǎn):SQL Server 需要 encrypt=true,如果無證書,加 trustServerCertificate=true
  • 跨域問題重點(diǎn):Spring Boot 后端必須添加 CORS 配置,否則前端 fetch 會被瀏覽器攔截。
  • 前端處理重點(diǎn):fetch 請求成功后由前端自己 window.location.href 跳轉(zhuǎn)。
  • 后端接口規(guī)范:登錄接口返回 200狀態(tài)+JSON,而不是 302重定向。
  • 安全建議:生產(chǎn)環(huán)境密碼應(yīng)加密存儲,使用 BCrypt 算法。

附錄:完整文件(可自行補(bǔ)全代碼)

pom.xml ?

<?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>org.example</groupId>
    <artifactId>BoounionERP</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <!-- Spring Boot 父項目 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.4.3</version>
        <relativePath/>
    </parent>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!-- Spring Boot Web 模塊(包含內(nèi)嵌 Tomcat) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- 開發(fā)工具(自動重啟,非必須) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- SQL Server JDBC 驅(qū)動 -->
        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>mssql-jdbc</artifactId>
            <version>11.2.3.jre11</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

index.html ?

<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <title>登錄界面</title>
  <style>
    body {
      font-family: Arial;
      padding: 50px;
      background-color: #f0f2f5;
    }
    .login-box {
      background-color: white;
      padding: 20px;
      width: 300px;
      margin: auto;
      border-radius: 5px;
      box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
    }
    input {
      width: 100%;
      margin-bottom: 10px;
      padding: 8px;
      box-sizing: border-box;
    }
    button {
      width: 100%;
      padding: 8px;
      background-color: #4CAF50;
      color: white;
      border: none;
      cursor: pointer;
    }
  </style>
</head>
<body>
  <div class="login-box">
    <h2>登錄</h2>
    <input type="text" id="username" placeholder="用戶名">
    <input type="password" id="password" placeholder="密碼">
    <button onclick="login()">登錄</button>
  </div>

  <script>
    function login() {
      const username = document.getElementById("username").value;
      const password = document.getElementById("password").value;

      fetch("/api/login", {
        method: "POST",
        headers: {
          "Content-Type": "application/json"
        },
        body: JSON.stringify({ username, password })
      })
      .then(response => response.json().then(data => ({ status: response.status, body: data })))
      .then(({ status, body }) => {
        if (status === 200 && body.status === "success") {
          window.location.href = body.redirectUrl;
        } else {
          alert(body.message || "登錄失敗");
        }
      })
      .catch(error => {
        alert("請求失敗,請檢查網(wǎng)絡(luò)");
        console.error(error);
      });
    }
  </script>
</body>
</html>

application.properties ?

# 數(shù)據(jù)庫連接配置
spring.datasource.url=jdbc:sqlserver://localhost:1433;databaseName=BoounionDB;encrypt=true;trustServerCertificate=true
spring.datasource.username=sa
spring.datasource.password=bl123456
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver

# 其他常規(guī)配置
spring.jpa.hibernate.ddl-auto=none
server.port=8080

Main.java ?

package org.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * ==================================================
 * This class Main is responsible for [功能描述].
 *
 * @author darker
 * @version 1.0
 * ==================================================
 */

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}

User.java ?

package org.example.model;

/**
 * ==================================================
 * This class User is responsible for [功能描述].
 *
 * @author darker
 * @version 1.0
 * ==================================================
 */

public class User {
    private String username;
    private String password;

    public User() {}

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    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; }
}

UserService.java ?

package org.example.service;

import org.example.model.User;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.sql.*;

/**
 * ==================================================
 * This class UserService is responsible for [功能描述].
 *
 * @author darker
 * @version 1.0
 * ==================================================
 */

@Service
public class UserService {
    @Value("${spring.datasource.url}")
    private String dbUrl;

    @Value("${spring.datasource.username}")
    private String dbUser;

    @Value("${spring.datasource.password}")
    private String dbPassword;

    public String login(User user) {
        try (Connection conn = DriverManager.getConnection(dbUrl, dbUser, dbPassword)) {

            String checkUserSql = "SELECT password FROM Users WHERE username = ?";
            try (PreparedStatement stmt = conn.prepareStatement(checkUserSql)) {
                stmt.setString(1, user.getUsername());

                try (ResultSet rs = stmt.executeQuery()) {
                    if (!rs.next()) {
                        return "用戶不存在";
                    }

                    String dbPassword = rs.getString("password");
                    if (!dbPassword.equals(user.getPassword())) {
                        return "密碼錯誤";
                    }

                    return "登錄成功";
                }
            }

        } catch (SQLException e) {
            e.printStackTrace();
            return "數(shù)據(jù)庫錯誤";
        }
    }
}

LoginController.java ?

package org.example.controller;

import org.example.model.User;
import org.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * ==================================================
 * This class LoginController is responsible for [功能描述].
 *
 * @author darker
 * @version 1.0
 * ==================================================
 */

@RestController
@RequestMapping("/api")
public class LoginController {
    @Autowired
    private UserService userService;

    @PostMapping("/login")
    public ResponseEntity<Map<String, Object>> login(@RequestBody User user) {
        String result = userService.login(user);
        Map<String, Object> response = new HashMap<>();

        switch (result) {
            case "登錄成功":
                // 拼接帶參數(shù)的跳轉(zhuǎn)地址
                /*
                 String url = String.format(
                        "https://www.baidu.com/s?username=%s",
                        user.getUsername()
                 );
                 */
                String url = "https://www.baidu.com/s?wd=csdn";
                response.put("status", "success");
                response.put("redirectUrl", url);
                return ResponseEntity.ok(response);
            case "密碼錯誤":
                response.put("status", "error");
                response.put("message", "密碼錯誤");
                return ResponseEntity.status(401).body(response);
            case "用戶不存在":
                response.put("status", "error");
                response.put("message", "用戶不存在");
                return ResponseEntity.status(404).body(response);
            default:
                response.put("status", "error");
                response.put("message", "服務(wù)器異常");
                return ResponseEntity.status(500).body(response);
        }
    }
}

到此這篇關(guān)于SpringBoot連接Microsoft SQL Server實現(xiàn)登錄驗證的文章就介紹到這了,更多相關(guān)SpringBoot連SQL登錄驗證內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Mybatis返回插入的主鍵問題解決方案

    Mybatis返回插入的主鍵問題解決方案

    這篇文章主要介紹了Mybatis返回插入的主鍵問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-09-09
  • 基于Eclipce配置Spring Boot過程圖解

    基于Eclipce配置Spring Boot過程圖解

    這篇文章主要介紹了基于Eclipce配置Spring Boot過程圖解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-03-03
  • 淺析Java多線程同步synchronized

    淺析Java多線程同步synchronized

    本篇文章給大家詳細(xì)分析了Java多線程同步synchronized的相關(guān)知識點(diǎn),需要的讀者們可以參考學(xué)習(xí)下。
    2018-02-02
  • Java并發(fā)編程之線程創(chuàng)建介紹

    Java并發(fā)編程之線程創(chuàng)建介紹

    這篇文章主要介紹了Java并發(fā)編程之線程創(chuàng)建,進(jìn)程是代碼在數(shù)據(jù)集合上的一次運(yùn)行活動,是系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位,線程則是一個實體,一個進(jìn)程中至少有一個線程,下文更多相關(guān)內(nèi)容需要的小伙伴可以參考一下
    2022-04-04
  • 深入解析Java中的編碼轉(zhuǎn)換以及編碼和解碼操作

    深入解析Java中的編碼轉(zhuǎn)換以及編碼和解碼操作

    這篇文章主要介紹了Java中的編碼轉(zhuǎn)換以及編碼和解碼操作,文中詳細(xì)解讀了編碼解碼的相關(guān)IO操作以及內(nèi)存使用方面的知識,需要的朋友可以參考下
    2016-02-02
  • idea啟動項目報端口號沖突或被占用的解決方法

    idea啟動項目報端口號沖突或被占用的解決方法

    這篇文章主要介紹了idea啟動項目報端口號沖突或被占用的解決方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-10-10
  • SpringBoot啟動類@SpringBootApplication注解背后的秘密

    SpringBoot啟動類@SpringBootApplication注解背后的秘密

    這篇文章主要介紹了SpringBoot啟動類@SpringBootApplication注解背后的秘密,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • SpringBoot 如何通過集成 Flink CDC 來實時追蹤 MySql 數(shù)據(jù)變動

    SpringBoot 如何通過集成 Flink CDC 來實時追蹤 M

    本文介紹如何在SpringBoot項目中集成FlinkCDC,實現(xiàn)對MySQL數(shù)據(jù)庫實時變動的捕獲與處理,包含環(huán)境準(zhǔn)備、依賴引入、作業(yè)配置及測試驗證等步驟,幫助開發(fā)者構(gòu)建高效的數(shù)據(jù)同步與分析應(yīng)用,感興趣的朋友一起看看吧
    2025-06-06
  • Java 創(chuàng)建URL的常見問題及解決方案

    Java 創(chuàng)建URL的常見問題及解決方案

    這篇文章主要介紹了Java 創(chuàng)建URL的常見問題及解決方案的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • SpringBoot讀取自定義配置文件方式(properties,yaml)

    SpringBoot讀取自定義配置文件方式(properties,yaml)

    這篇文章主要介紹了SpringBoot讀取自定義配置文件方式(properties,yaml),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07

最新評論

邯郸县| 临邑县| 阳高县| 东安县| 枣庄市| 浮梁县| 彩票| 乌拉特前旗| 梓潼县| 龙川县| 临汾市| 潞西市| 茌平县| 叶城县| 仙桃市| 溧阳市| 夏邑县| 改则县| 祁东县| 湟源县| 无为县| 双峰县| 旅游| 依安县| 登封市| 留坝县| 成安县| 晋中市| 大荔县| 铜鼓县| 连平县| 固安县| 平果县| 墨脱县| 黑龙江省| 海淀区| 腾冲县| 台江县| 鄂尔多斯市| 千阳县| 汤阴县|