基于springboot+mybatis-plus的登陆系统开发(含完整代码)

登陆系统

项目介绍

  • 本项目是采用Java语言开发的Web应用,集成了Spring Boot框架、MyBatis-Plus持久层框架以及Thymeleaf模板引擎,旨在构建一个功能完善的用户登录系统。通过综合运用这些先进技术,我们实现了一个高效、稳定且用户友好的登录界面及其后端处理逻辑。

项目结构

logintest/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/example/logintest/
│ │ │ ├── LogintestApplication.java
│ │ │ ├── controller/
│ │ │ │ ├── LogintestController.java
│ │ │ │ ├── RegisterController.java
│ │ │ ├── model/
│ │ │ │ ├── User.java
│ │ │ ├── mapper/
│ │ │ │ ├── UserMapper.java
│ │ │ └── service/
│ │ │ ├── UserService.java
│ │ │ │ └── impl/
│ │ │ │ ├──UserServiceimpl.java
│ │ └── resources/
│ │ └── static/
│ │ └── templaes/
│ │ │ ├──login.html
│ │ │ ├──register.html
│ │ │ ├──home.html
│ │ ├── application.yml
└── pom.xml

数据库

Mysql使用sql语句创建一个新的表

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    password VARCHAR(255) NOT NULL,
    email VARCHAR(100) NOT NULL,
    UNIQUE (username),
    UNIQUE (email));

id:一个自增的主键字段,用于唯一标识每一条记录。
username:用户的用户名,最大长度为 50 个字符,不允许为空,并且要求唯一。
password:用户的密码,最大长度为 255 个字符,不允许为空。密码字段长度可以根据实际情况调整,以适应加密存储。
email:用户的电子邮箱,最大长度为 100 个字符,不允许为空,并且要求唯一。
UNIQUE 约束确保 username 和 email 在表中唯一。你可以根据需要调整字段的长度和约束条件。

配置文件

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <!-- POM 文件的模型版本 -->
    <modelVersion>4.0.0</modelVersion>

    <!-- 指定父级 POM 文件,继承 Spring Boot 的父 POM 配置 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.2</version>
        <relativePath/> <!-- 从仓库查找父 POM -->
    </parent>

    <!-- 项目的基本信息 -->
    <groupId>com.example</groupId>
    <artifactId>logintest</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>logintest</name>
    <description>logintest</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>

    <!-- 定义项目的属性 -->
    <properties>
        <!-- 指定 Java 版本 -->
        <java.version>17</java.version>
        <!-- Spring Boot 版本 -->
        <spring.boot.version>3.3.0</spring.boot.version>
        <!-- MyBatis-Plus 版本 -->
        <mybatis-plus.version>3.5.0</mybatis-plus.version>
    </properties>

    <!-- 项目的依赖项 -->
    <dependencies>
        <!-- Spring Boot Thymeleaf 启动器,用于模板引擎 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
            <version>3.3.2</version>
        </dependency>
        
        <!-- Spring Boot Web 启动器,包含 Web 开发相关的库 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- MySQL JDBC 驱动,运行时依赖 -->
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        
        <!-- MyBatis-Plus Spring Boot 3 启动器,简化 MyBatis 的配置 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
            <version>3.5.5</version>
        </dependency>

        <!-- Lombok,简化 Java 代码的库,作为可选依赖 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Spring Boot 测试启动器,用于测试 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <!-- 项目的构建配置 -->
    <build>
        <plugins>
            <!-- Spring Boot Maven 插件,用于构建 Spring Boot 应用 -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>3.3.1</version>
                <configuration>
                    <excludes>
                        <!-- 排除 Lombok 库,防止将其打包到最终的应用程序中 -->
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build></project>
注释详细说明
  1. <modelVersion>: 指定 POM 文件的模型版本,通常为 4.0.0
  2. <parent>: 指定继承的父 POM 文件,spring-boot-starter-parent 是 Spring Boot 提供的一个父 POM,它提供了很多默认的配置。
  3. <groupId>: 项目的组 ID,一般是组织名或公司名,通常与 Maven 仓库的路径一致。
  4. <artifactId>: 项目的 artifact ID,通常是项目名。
  5. <version>: 项目的版本号。
  6. <name>: 项目的名称。
  7. <description>: 对项目的简短描述。
  8. <url>: 项目主页的 URL,通常留空。
  9. <licenses>: 项目的许可信息,通常留空。
  10. <developers>: 项目的开发者信息,通常留空。
  11. <scm>: 项目的源码管理信息,通常留空。
  12. <properties>: 项目的属性定义,包括 Java 版本、Spring Boot 版本和 MyBatis-Plus 版本等。
  13. <dependencies>: 项目的依赖项,包括 Spring Boot 启动器、数据库驱动、MyBatis-Plus、Lombok 等。
  14. <build>: 项目的构建配置,包括 Maven 插件的配置。这里使用了 spring-boot-maven-plugin 插件,并排除了 Lombok 库的打包。
applicatio.yml
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/ems-thymeleaf # 数据库连接 URL
    username: root # 数据库用户名
    password: 123456 # 数据库密码
    driver-class-name: com.mysql.cj.jdbc.Driver # JDBC 驱动类
  jpa:
    hibernate:
      ddl-auto: update # 自动更新数据库表结构
    show-sql: true # 显示 SQL 语句
  thymeleaf:
    cache: false # 禁用模板缓存mybatis-plus:
  mapper-locations: classpath*:/mapper/*.xml # MyBatis XML 映射文件位置
  typeAliasesPackage: com.example.logintest.model # MyBatis 类型别名包

Spring Boot 应用的主类

LogintestApplication.java 是一个典型的 Spring Boot 应用的主类。这个类通常包含应用程序的入口点,即 main 方法,是 Spring Boot 应用启动的起点。

LogintestApplication.java
package com.example.logintest;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * Spring Boot 应用的启动类。
 * 这个类是 Spring Boot 应用的入口点,用于启动应用程序。
 */@SpringBootApplication // 标记这是一个 Spring Boot 应用的主类@MapperScan("com.example.logintest.mapper") // 扫描指定包下的 Mapper 接口public class LogintestApplication {

    /**
     * 应用程序的入口点。
     * @param args 命令行参数
     */
    public static void main(String[] args) {
        // 启动 Spring Boot 应用
        SpringApplication.run(LogintestApplication.class, args);
    }
}

Controller控制器类

LogintestController.java
package com.example.logintest.controller;

import com.example.logintest.model.User;
import com.example.logintest.service.UserService;
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;
import org.springframework.web.bind.annotation.RequestParam;

/** 处理用户登录请求的控制器类。 */@Controllerpublic class LoginController {

    /**  注入 UserService 实例,用于处理与用户相关的业务逻辑。 */
    @Autowired
    private UserService userService;

    /**
     * 显示登录页面的处理方法。@return 登录页面的视图名称*/
    @GetMapping("/login")
    public String login() {
        // 返回视图名 "login",即 login.html 或 login.jsp 页面
        return "login";
    }

    /**
     * 处理用户提交的登录表单请求。
     * @param username 用户名
     * @param password 密码
     * @param model Spring MVC 的 Model 对象,用于传递数据到视图
     * @return 登录成功后转向的页面,或登录失败时返回的视图
     */
    @PostMapping("/login")
    public String login(@RequestParam String username, @RequestParam String password, Model model) {
        // 通过 UserService 查找用户
        User user = userService.findByUsername(username);

        // 验证用户名和密码是否匹配
        if (user != null && user.getPassword().equals(password)) {
            // 登录成功,返回 "home" 视图(例如 home.html 或 home.jsp 页面)
            return "home";
        } else {
            // 登录失败,将错误信息添加到 Model 对象,并返回 "login" 视图
            model.addAttribute("error", "Invalid username or password");
            return "login";
        }
    }
}
RegisterController.java
package com.example.logintest.controller;

import com.example.logintest.model.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controllerpublic class RegisterController {

    @PostMapping("/register")
    public String register(@RequestParam String username, @RequestParam String password, @RequestParam String email) {
        // 使用全参构造函数
        User newUser = new User(null, username, password, email);
        // 其他注册逻辑
        return "registrationSuccess";
    }
}

model(模型)

  • 定义: Model 类通常用于表示应用程序中的数据对象,不一定与数据库表直接对应。它们用于表示业务逻辑中的数据结构。
  • 注解: Model 类通常不需要 JPA 注解,它们可能被用于不同的目的,如数据传输(DTO),业务逻辑处理等。
  • 职责: 用于封装和传递数据,可能涉及业务逻辑处理和数据展示等。
Uesr.java
package com.example.logintest.model;

// 导入 MyBatis-Plus 和 Lombok 的相关注解import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;

// Lombok 注解:自动生成 getter、setter 方法,以及 toString、equals 和 hashCode 方法@Data// Lombok 注解:生成一个无参数的构造函数@NoArgsConstructor// Lombok 注解:生成一个包含所有字段的构造函数@AllArgsConstructor// MyBatis-Plus 注解:指定数据库中的表名,这里将 User 类映射到 users 表@TableName("users")
public class User {
    // MyBatis-Plus 注解:指定 id 字段为主键,并且主键生成策略为自动生成(自增)
    @TableId(type = IdType.AUTO)
    private Integer id; // 用户的唯一标识符

    private String username; // 用户名

    private String password; // 用户密码

    private String email; // 用户邮箱
}

mapper 接口类

mapper.java(创建时选择接口类)
package com.example.logintest.mapper;

// 导入 MyBatis-Plus 的 BaseMapper 和 MyBatis 的 Mapper 注解import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.logintest.model.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

// MyBatis 注解:标识这是一个 MyBatis 的 Mapper 接口@Mapperpublic interface UserMapper extends BaseMapper<User> {

    // MyBatis 注解:执行 SQL 查询语句,查找具有指定用户名的用户
    @Select("SELECT * FROM users WHERE username = #{username}")

    //User 是返回类型  findByUsername 是参数   String username  是方法参数
    User findByUsername(String username);
}

service 业务逻辑处理类和接口

  1. 业务逻辑处理:

    • service 包中的类主要负责处理应用程序的业务逻辑。这些类通常包含应用程序的核心逻辑,比如处理数据、执行计算、调用其他服务等。
  2. 服务层:

    • 在分层架构中,service 包代表了服务层,它位于控制层(controller 包)和数据访问层(repositorymapper 包)之间。服务层负责从数据访问层获取数据,并对这些数据进行处理,然后将结果返回给控制层。
  3. 事务管理:

    • 服务层通常会管理事务,确保数据的一致性和完整性。使用 Spring 框架时,服务层的方法可以通过 @Transactional 注解来控制事务的开始和结束。
  4. 业务规则实现:

    • 在服务层中实现应用程序的业务规则,确保业务流程按照预期执行。
      在Java项目中,特别是在使用Spring框架或类似的企业级Java应用中,service包通常用于存放服务层(Service Layer)的接口和类。服务层是应用程序架构中的一个重要组成部分,它位于控制层(Controller Layer)和数据访问层(Data Access Layer,如Repository或DAO)之间,负责处理业务逻辑。
  5. service.impl包

    • 包含服务接口的具体实现类,这些类实现了service包中定义的服务接口。
    • 实现类通常以“接口名 + Impl”的命名约定来命名,例如UserServiceImpl实现了UserService接口。
    • 在这些实现类中,你会找到业务逻辑的具体代码,包括数据验证、业务规则处理、调用数据访问层等。

service包下的impl包(implementation的缩写)是一个常见的约定,用于存放服务接口的具体实现类。这种分包结构有助于保持代码的整洁和模块化,使得接口定义和实现细节分离。

impl/UserServiceImpl.java
package com.example.logintest.service.impl;  // 包名,表示该类位于 service.impl 包中

import com.example.logintest.mapper.UserMapper;  // 导入 UserMapper 类,负责与数据库进行交互import com.example.logintest.model.User;  // 导入 User 类,表示用户数据模型import com.example.logintest.service.UserService;  // 导入 UserService 接口,定义了服务的操作import org.springframework.beans.factory.annotation.Autowired;  // 导入 @Autowired 注解,用于依赖注入import org.springframework.stereotype.Service;  // 导入 @Service 注解,标记这是一个服务组件

@Service  // 标记这个类是一个 Spring 服务组件,将其交给 Spring 容器进行管理public class UserServiceImpl extends UserService {  // 实现 UserService 接口

    @Autowired  // 自动注入 UserMapper 的实例
    private UserMapper userMapper;  // 用于与数据库交互,执行实际的数据操作

    @Override  // 实现 UserService 接口中的方法
    public User findByUsername(String username) {
        return userMapper.findByUsername(username);  // 调用 UserMapper 的方法查找用户并返回结果
    }
}
UserService.java
package com.example.logintest.service;

import com.example.logintest.model.User;
import org.springframework.stereotype.Service;

@Servicepublic abstract class UserService {

    // 模拟用户存储(通常会使用数据库)
    public boolean saveUser(User user) {
        // TODO: 实现用户存储逻辑,例如使用数据库保存用户
        return true;
    }

    public abstract User findByUsername(String username);
}

templates/

templates 包在 Java 项目中主要用于存放各种模板文件,这些文件会在应用运行时被动态渲染。无论是生成 HTML 页面、邮件内容还是其他类型的输出,模板文件都是支持动态内容生成的重要工具。

login.html
<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org"><head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>登录 - 后台管理系统</title>
    <link rel="stylesheet" href="css/admin-styles.css">
    <style>
        /* 内联样式,确保页面样式符合设计需求 */
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            background-color: #f4f4f4; /* 背景颜色 */
        }

        .login-container {
            background-color: #ffffff; /* 登录框背景颜色 */
            padding: 2rem;
            border-radius: 8px;
            box-shadow: 0 0 15px rgba(0, 0, 0, 0.1);
            width: 300px;
        }

        .login-container h2 {
            margin-bottom: 1rem;
            text-align: center;
            color: #333;
        }

        .login-container form {
            display: flex;
            flex-direction: column;
        }

        .login-container form div {
            margin-bottom: 1rem;
        }

        .login-container form label {
            display: block;
            margin-bottom: 0.5rem;
            color: #555;
        }

        .login-container form input {
            width: 100%;
            padding: 0.5rem;
            border: 1px solid #ddd;
            border-radius: 4px;
            box-sizing: border-box;
        }

        .login-container form button {
            padding: 0.75rem;
            background-color: #007BFF;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 1rem;
            font-weight: bold;
            transition: background-color 0.3s ease;
        }

        .login-container form button:hover {
            background-color: #0056b3;
        }

        .login-container form hr {
            margin: 1.5rem 0; /* 分界线上下间距 */
            border: none;
            height: 1px;
            background-color: #ddd; /* 分界线颜色 */
        }

        .login-container form .error-message {
            color: red;
            text-align: center;
            margin-top: 1rem;
        }
    </style></head><body><div class="login-container">
    <h2>登录</h2>
    <form action="/login" method="post" id="login-form">
        <div>
            <label for="username">用户名:</label>
            <input type="text" id="username" name="username" required>
        </div>
        <div>
            <label for="password">密码:</label>
            <input type="password" id="password" name="password" required>
        </div>
        <button type="submit">登录</button>
        <hr> <!-- 分界线 -->
        <button type="button" onclick="window.location.href='register.html'">注册</button>
        <div class="error-message" th:if="${error}">
            <p th:text="${error}"></p>
        </div>
    </form></div></body></html>
home.html
<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org"><head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>后台管理系统</title>
    <link rel="stylesheet" href="css/admin-styles.css">
    <style>
        /* 内联样式,确保页面样式符合设计需求 */
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            background-color: #f4f4f4; /* 背景颜色 */
        }

        header {
            background-color: #333;
            color: white;
            padding: 1rem;
            text-align: center;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
        }

        .admin-container {
            display: flex;
            min-height: calc(100vh - 60px); /* 确保内容区域至少占据视口高度 */
        }

        .sidebar {
            width: 220px;
            background-color: #ffffff;
            padding: 1rem;
            box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);
            overflow-y: auto; /* 支持滚动 */
        }

        .sidebar nav ul {
            list-style: none;
            padding: 0;
        }

        .sidebar nav ul li {
            margin: 1rem 0;
        }

        .sidebar nav ul li a {
            text-decoration: none;
            color: #333;
            font-size: 1rem;
            font-weight: bold;
            display: block;
            padding: 0.5rem;
            border-radius: 4px;
            transition: background-color 0.3s ease;
        }

        .sidebar nav ul li a:hover {
            background-color: #e9ecef;
        }

        .content {
            flex: 1;
            padding: 2rem;
            background-color: #ffffff;
        }

        .content h2 {
            margin-top: 0;
            color: #333;
        }

        .content button {
            padding: 0.75rem 1.25rem;
            background-color: #007BFF;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 1rem;
            font-weight: bold;
            transition: background-color 0.3s ease;
        }

        .content button:hover {
            background-color: #0056b3;
        }

        table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 1rem;
        }

        table, th, td {
            border: 1px solid #ddd;
        }

        th, td {
            padding: 0.75rem;
            text-align: left;
        }

        th {
            background-color: #f4f4f4;
        }

        footer {
            background-color: #333;
            color: white;
            text-align: center;
            padding: 1rem;
            position: fixed;
            bottom: 0;
            width: 100%;
            box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.1);
        }
    </style></head><body><header>
    <h1>后台管理系统</h1></header>

<div class="admin-container">
    <aside class="sidebar">
        <nav>
            <ul>
                <li><a href="#manage-foods">管理美食列表</a></li>
                <li><a href="#manage-users">用户管理</a></li>
                <li><a href="#statistics">统计分析</a></li>
                <li><a href="#settings">其他设置</a></li>
            </ul>
        </nav>
    </aside>

    <main class="content">
        <section id="manage-foods">
            <h2>管理美食列表</h2>
            <button id="add-food">添加美食</button>
            <table id="food-table">
                <thead>
                <tr>
                    <th>ID</th>
                    <th>名称</th>
                    <th>描述</th>
                    <th>操作</th>
                </tr>
                </thead>
                <tbody>
                <!-- 美食数据会动态插入这里 -->
                </tbody>
            </table>
        </section>

        <section id="manage-users">
            <h2>用户管理</h2>
            <button id="add-user">添加用户</button>
            <table id="user-table">
                <thead>
                <tr>
                    <th>ID</th>
                    <th>用户名</th>
                    <th>邮箱</th>
                    <th>操作</th>
                </tr>
                </thead>
                <tbody>
                <!-- 用户数据会动态插入这里 -->
                </tbody>
            </table>
        </section>

        <section id="statistics">
            <h2>统计分析</h2>
            <p>这里显示统计信息和系统概况。</p>
        </section>

        <section id="settings">
            <h2>其他设置</h2>
            <p>这里是其他设置项。</p>
        </section>
    </main></div>

<footer>
    <p>&copy; 2024 后台管理系统</p></footer>

<script src="js/admin-scripts.js"></script></body></html>
register.html
<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org"><head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>注册 - 后台管理系统</title>
    <link rel="stylesheet" href="css/admin-styles.css">
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            background-color: #f4f4f4;
        }

        .register-container {
            background-color: #ffffff;
            padding: 2rem;
            border-radius: 8px;
            box-shadow: 0 0 15px rgba(0, 0, 0, 0.1);
            width: 300px;
        }

        .register-container h2 {
            margin-bottom: 1rem;
            text-align: center;
            color: #333;
        }

        .register-container form {
            display: flex;
            flex-direction: column;
        }

        .register-container form div {
            margin-bottom: 1rem;
        }

        .register-container form label {
            display: block;
            margin-bottom: 0.5rem;
            color: #555;
        }

        .register-container form input {
            width: 100%;
            padding: 0.5rem;
            border: 1px solid #ddd;
            border-radius: 4px;
            box-sizing: border-box;
        }

        .register-container form button {
            padding: 0.75rem;
            background-color: #007BFF;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 1rem;
            font-weight: bold;
            transition: background-color 0.3s ease;
        }

        .register-container form button:hover {
            background-color: #0056b3;
        }

        .register-container form hr {
            margin: 1.5rem 0;
            border: none;
            height: 1px;
            background-color: #ddd;
        }

        .register-container .login-link {
            text-align: center;
            margin-top: 1rem;
        }

        .register-container .login-link a {
            text-decoration: none;
            color: #007BFF;
        }

        .register-container .error-message {
            color: red;
            text-align: center;
            margin-top: 1rem;
        }
    </style></head><body><div class="register-container">
    <h2>注册</h2>
    <form action="#" th:action="@{/register}" method="post" id="register-form">
        <div>
            <label for="username">用户名:</label>
            <input type="text" id="username" name="username" required>
        </div>
        <div>
            <label for="email">邮箱:</label>
            <input type="email" id="email" name="email" required>
        </div>
        <div>
            <label for="password">密码:</label>
            <input type="password" id="password" name="password" required>
        </div>
        <div>
            <label for="confirm-password">确认密码:</label>
            <input type="password" id="confirm-password" name="confirm-password" required>
        </div>
        <button type="submit">注册</button>
        <hr>
        <div class="login-link">
            <p>已有账户?<a href="login.html">登录</a></p>
        </div>
        <div class="error-message" th:if="${error}">
            <p th:text="${error}"></p>
        </div>
    </form></div></body></html>

                
  • 38
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值