JavaEE 实现 登录+注册(采用注解方式链接数据库)

news2024/11/24 13:19:13

(Spring MVC的Controller练习)

工具:Tomcat 10.0.23,MySQL,JDK18

一、运行效果展示

点击运行Tomcat首先进入index.jsp页面

若已有账号点击登录即可进行登录,这里先点击“获取ROY6账号”去注册,进入register.jsp页面

注册成功后跳转到success.jsp页面,此时数据库中user表会增加一条用户信息

点击“前往探索ROY6商城此时,此时为login.jsp页面

输入已经注册过的账号,登录,进入welcome.jsp页面

这里我简单的写了两个小功能,就不进行展示了,本文主要展示登录注册功能。

下面进入详细操作步骤,请慢慢食用代码!

二、项目代码

先查看项目结构图:

红色框出部分为本次实验用到代码

 

1、建立数据库,建表

首先创建数据库spring_db,然后建立所需要的用户表user

CREATE DATABASE IF NOT EXISTS spring_db CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

USE spring_db;

CREATE TABLE user (
                      id INT AUTO_INCREMENT PRIMARY KEY,
                      username VARCHAR(50) NOT NULL UNIQUE,
                      password VARCHAR(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

 2、创建第一个index.jsp页面

页面主要包含注册以及登陆,很简单,直接放代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>欢迎</title>
    <style>
        /* 页面背景 */
        body {
            font-family: 'Arial', sans-serif;
            margin: 0;
            padding: 0;
            background: url('https://wx3.sinaimg.cn/mw690/007doFNOgy1hf8lzl0rs2j323u16q7wh.jpg') no-repeat center center fixed;
            background-size: cover;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            overflow: hidden;
            animation: backgroundAnimation 10s infinite alternate;
        }

        /* 页面内容容器 */
        .container {
            text-align: center;
            background-color: white;
            padding: 40px;
            border-radius: 12px;
            box-shadow: 0 6px 15px rgba(0, 0, 0, 0.1); /* 阴影效果 */
            background-color: rgba(255, 255, 255, 0.95); /* 背景半透明 */
            width: 100%;
            max-width: 500px;
        }

        /* 标题样式 */
        h3 {
            font-family: 'Comic Sans MS', cursive, sans-serif; /* 卡通风格字体 */
            font-size: 28px;
            color: #00BFFF; /* 天青色 */
            margin-bottom: 20px;
        }

        /* 链接列表样式 */
        ul {
            list-style-type: none;
            padding: 0;
        }

        li {
            margin: 15px 0;
        }

        /* 链接按钮样式 */
        a {
            text-decoration: none;
            padding: 12px 25px;
            background-color: #607d8b; /* 莫兰迪蓝绿色 */
            color: white;
            font-size: 18px;
            border-radius: 10px;
            display: inline-block;
            transition: background-color 0.3s ease, transform 0.2s ease;
        }

        a:hover {
            background-color: #78909c;
            transform: translateY(-2px);
        }

        a:active {
            background-color: #546e7a;
            transform: translateY(0);
        }

        /* 响应式设计 */
        @media (max-width: 480px) {
            .container {
                padding: 20px;
                width: 90%;
            }

            h3 {
                font-size: 24px;
            }

            a {
                font-size: 16px;
                padding: 10px 20px;
            }
        }
    </style>
</head>
<body>

<div class="container">
    <h3>${username} 欢迎你的探索!</h3>
    <ul>
        <li><a href="index/login">登录</a></li>
        <li><a href="index/register">获取ROY6账号</a></li>
    </ul>
</div>

</body>
</html>

 3、注册页面 register.jsp页面

由index.jsp页面点击注册按钮跳转而来,主要实现注册功能。这里连接数据库,判断用户的合法性。注册成功跳转success.jsp页面,失败跳转到error.jsp页面,已经注册过则继续停留在此页面,提示“注册失败,用户名已存在“。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>注册</title>
    <style>
        body {
            font-family: 'Arial', sans-serif;
            margin: 0;
            padding: 0;
            background: url('https://wx4.sinaimg.cn/mw690/007btvx7ly1h7zumoa5l8j30u01mtgru.jpg') no-repeat center center fixed;
            background-size: cover;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            overflow: hidden;
            animation: backgroundAnimation 10s infinite alternate;
        }

        .container {
            width: 100%;
            max-width: 400px;
            background-color: #ffffff;
            padding: 30px;
            border-radius: 12px;
            box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
            animation: fadeIn 0.8s ease-in-out;
        }

        @keyframes fadeIn {
            from {
                opacity: 0;
                transform: translateY(-20px);
            }
            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        h2 {
            font-size: 28px;
            color: #7a7975; /* 莫兰迪灰色 */
            margin-bottom: 20px;
            text-align: center;
            font-family: 'Comic Sans MS', cursive;
        }

        .form-group {
            margin-bottom: 20px;
        }

        .form-group label {
            font-size: 16px;
            color: #8A9A8E; /* 深莫兰迪灰褐色 */
            margin-bottom: 5px;
            display: block;
            text-align: left;
        }

        .form-group input {
            width: 100%;
            padding: 12px;
            font-size: 16px;
            border: 1px solid #ddd;
            border-radius: 8px;
            box-sizing: border-box;
            outline: none;
            transition: all 0.3s ease;
        }

        .form-group input:focus {
            border-color: #a6a398; /* 莫兰迪绿灰色 */
            box-shadow: 0 0 10px rgba(166, 163, 152, 0.3);
        }

        .form-group p {
            color: #c94e50; /* 柔和的莫兰迪红色 */
            font-size: 14px;
        }

        .button-container {
            display: flex;
            gap: 10px;
            justify-content: space-between;
        }

        .button-container button {
            width: 48%;
            padding: 12px;
            font-size: 16px;
            border-radius: 8px;
            border: none;
            cursor: pointer;
            transition: all 0.3s ease;
        }

        .reset-button {
            background-color: #d7d3cc; /* 莫兰迪浅灰色 */
            color: #4f4d49; /* 深莫兰迪灰 */
        }

        .reset-button:hover {
            background-color: #c8c4bb; /* 更深的莫兰迪灰 */
        }

        .submit-button {
            background-color: #A8B3A5; /* 莫兰迪绿灰色 */
            color: #ffffff;
        }

        .submit-button:hover {
            background-color: #8f8c80; /* 更深的莫兰迪绿灰色 */
        }

        @media (max-width: 480px) {
            .container {
                padding: 20px;
            }

            h2 {
                font-size: 24px;
            }

            .form-group label {
                font-size: 14px;
            }

            .form-group input {
                font-size: 14px;
                padding: 10px;
            }

            .button-container button {
                font-size: 14px;
                padding: 10px;
            }
        }
    </style>
</head>
<body>
<div class="container">
    <h2>注册</h2>
    <%
        String error = (String) request.getAttribute("error");
        if (error != null) {
    %>
    <div class="form-group">
        <p><%= error %></p>
    </div>
    <%
        }
    %>
    <form action="${pageContext.request.contextPath}/doRegister" method="post">
        <div class="form-group">
            <label for="registerUsername">用户名</label>
            <input type="text" id="registerUsername" name="username" required>
        </div>
        <div class="form-group">
            <label for="password">密码</label>
            <input type="password" id="password" name="password" required>
        </div>
        <div class="form-group">
            <label for="confirmPassword">确认密码</label>
            <input type="password" id="confirmPassword" name="confirmPassword" required>
        </div>
        <div class="button-container">
            <button type="reset" class="reset-button">重置</button>
            <button type="submit" class="submit-button">注册</button>
        </div>
    </form>
</div>
</body>
</html>

 4、注册成功success.jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>注册成功</title>
    <style>
        body {
            font-family: 'Arial', sans-serif;
            margin: 0;
            padding: 0;
            background: url('https://wx2.sinaimg.cn/mw690/006Gi90nly1h6p18g6sipj31h40u0791.jpg') no-repeat center center fixed;
            background-size: cover;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            overflow: hidden;
            animation: backgroundAnimation 10s infinite alternate;
        }

        .container {
            background-color: white;
            padding: 40px;
            background-color: rgba(255, 255, 255, 0.95); /* 背景半透明 */
            border-radius: 16px;
            box-shadow: 0 6px 15px rgba(0, 0, 0, 0.1); /* 阴影效果 */
            width: 100%;
            max-width: 420px;
            text-align: center;
        }

        h1 {
            font-family: 'Comic Sans MS', cursive, sans-serif; /* 可爱的卡通字体 */
            font-size: 36px;
            color: #c58e72;
            margin-bottom: 20px;
            font-weight: 600;
        }

        p {
            font-size: 18px;
            color: #333;
            margin-bottom: 30px;
        }

        a {
            display: inline-block;
            font-size: 18px;
            color: white;
            background-color: #607d8b; /* Morandi blue */
            padding: 12px 24px;
            text-decoration: none;
            border-radius: 10px;
            transition: background-color 0.3s ease, transform 0.2s ease;
        }

        a:hover {
            background-color: #78909c;
            transform: translateY(-2px);
        }

        a:active {
            background-color: #546e7a;
            transform: translateY(1px);
        }
    </style>
</head>
<body>

<div class="container">
    <h1>注册成功</h1>
    <p>欢迎,您已成为ROY6新成员!</p>
    <a href="${pageContext.request.contextPath}/login">前往探索ROY6商城</a>
</div>

</body>
</html>

5、注册失败error.jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>注册失败</title>
    <style>
        /* 设置背景色 */
        body {
            font-family: Arial, sans-serif;
            background-color: #f8d7da; /* 轻微红色背景,表示失败 */
            margin: 0;
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        .container {
            text-align: center;
            background-color: white;
            padding: 30px 50px;
            border-radius: 10px;
            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
            width: 100%;
            max-width: 400px;
        }

        h1 {
            font-size: 24px;
            color: #721c24; /* 错误提示的红色 */
            margin-bottom: 20px;
        }

        p {
            font-size: 18px;
            color: #721c24;
            margin-bottom: 30px;
        }

        a {
            text-decoration: none;
            padding: 12px 20px;
            background-color: #4CAF50;
            color: white;
            font-size: 16px;
            font-weight: bold;
            border-radius: 6px;
            display: inline-block;
            transition: background-color 0.3s ease, transform 0.2s ease;
        }

        a:hover {
            background-color: #45a049;
            transform: translateY(-2px);
        }

        a:active {
            transform: translateY(0);
        }
    </style>
</head>
<body>

<div class="container">
    <h1>注册失败</h1>
    <p>抱歉,您的注册未能成功。请重试</p>
    <a href="${pageContext.request.contextPath}/register">返回注册页面</a>
</div>
</body>
</html>

6、登录login.jsp页面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>登录</title>
    <style>

        /* 页面基础样式 */
        body {
            font-family: 'Arial', sans-serif;
            margin: 0;
            padding: 0;
            background: url('https://wx4.sinaimg.cn/mw690/007btvx7ly1h7zumt0ty2j31hc0u0wkx.jpg') no-repeat center center fixed;
            background-size: cover;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            overflow: hidden;
            animation: backgroundAnimation 10s infinite alternate;
        }

        .container {
            width: 100%;
            max-width: 400px;
            padding: 40px;
            background-color: rgba(255, 255, 255, 0.95); /* 背景半透明 */
            border-radius: 12px;
            box-shadow: 0 6px 15px rgba(0, 0, 0, 0.1); /* 阴影效果 */
            text-align: center;
            animation: fadeIn 1s ease-in-out;
        }

        /* 标题样式:使用莫兰迪色系 */
        h2 {
            font-size: 30px;
            color: #A8B3A5; /* 莫兰迪绿 */
            font-weight: 600;
            margin-bottom: 30px;
            letter-spacing: 1px;
            font-family: 'Georgia', serif;
        }

        /* 表单样式 */
        form {
            display: flex;
            flex-direction: column;
            gap: 20px;
        }

        .form-group {
            display: flex;
            flex-direction: column;
            align-items: flex-start;
        }

        .form-group label {
            margin-bottom: 8px;
            font-weight: bold;
            color: #6D7D6E; /* 莫兰迪灰绿 */
        }

        .form-group input {
            width: 100%;
            padding: 12px;
            border: 1px solid #ddd;
            border-radius: 8px;
            font-size: 16px;
            transition: border-color 0.3s ease, box-shadow 0.3s ease;
        }

        /* 输入框聚焦效果 */
        .form-group input:focus {
            border-color: #A8B3A5; /* 莫兰迪绿 */
            outline: none;
            box-shadow: 0 0 8px rgba(169, 179, 165, 0.6);
        }

        /* 按钮样式 */
        .form-group button {
            padding: 12px 20px;
            border: none;
            border-radius: 6px;
            background-color: #A8B3A5; /* 莫兰迪绿 */
            color: white;
            font-size: 16px;
            font-weight: bold;
            cursor: pointer;
            transition: background-color 0.3s ease, transform 0.2s ease;
        }

        .form-group button:hover {
            background-color: #8A9A8E; /* 更深的莫兰迪绿 */
            transform: translateY(-3px);
        }

        .form-group button:active {
            transform: translateY(0);
        }

        /* 提交按钮 */
        .submit-button {
            background-color: #A8B3A5;
        }

        .submit-button:hover {
            background-color: #8A9A8E;
        }

        /* 动画效果 */
        @keyframes fadeIn {
            from {
                opacity: 0;
                transform: translateY(-20px);
            }
            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        /* 响应式设计 */
        @media (max-width: 480px) {
            .container {
                padding: 20px;
            }

            .form-group input {
                padding: 10px;
            }

            .form-group button {
                padding: 12px 16px;
            }

            h2 {
                font-size: 26px;
            }
        }
    </style>
</head>
<body>

<div class="container">
    <h2>登录</h2>
    <form action="${pageContext.request.contextPath}/doLogin" method="post">
        <div class="form-group">
            <label for="username">用户名</label>
            <input type="text" id="username" name="username" required>
        </div>
        <div class="form-group">
            <label for="password">密码</label>
            <input type="password" id="password" name="password" required>
        </div>
        <div class="form-group">
            <button type="submit" class="submit-button">登录</button>
        </div>
    </form>
</div>

</body>
</html>

7、欢迎welcome.jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>欢迎来到ROY6商城</title>
    <style>
        body {
            font-family: 'Arial', sans-serif;
            margin: 0;
            padding: 0;
            background: url('https://wx4.sinaimg.cn/mw690/007doFNOgy1hf8lzljzodj323u16qqv5.jpg') no-repeat center center fixed;
            background-size: cover;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            overflow: hidden;
        }

        .container {
            text-align: center;
            background-color: rgba(255, 255, 255, 0.9);
            padding: 30px 40px;
            border-radius: 15px;
            box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2);
            width: 100%;
            max-width: 500px;
            animation: fadeIn 1s ease-in-out;
            position: relative;
            z-index: 1;
        }

        h1 {
            font-size: 30px;
            color: #444;
            margin-bottom: 20px;
            font-family: 'Comic Sans MS', cursive;
        }

        p {
            font-size: 18px;
            color: #666;
            margin-bottom: 20px;
        }

        a {
            display: inline-block;
            text-decoration: none;
            padding: 12px 25px;
            margin: 10px 0;
            background-color: #A8B3A5; /* 修改为莫兰迪绿色 */
            color: white;
            font-size: 16px;
            border-radius: 8px;
            transition: background-color 0.3s ease, transform 0.2s ease;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
        }

        a:hover {
            background-color: #8A9A8E; /* 悬停时更深的莫兰迪绿色 */
            transform: translateY(-3px);
        }

        a:active {
            transform: translateY(0);
        }

        @keyframes fadeIn {
            from {
                opacity: 0;
                transform: translateY(-20px);
            }
            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        /* 新增样式:绝对定位文本 */
        .text-overlay {
            position: absolute;
            top: 10%;
            left: 50%;
            transform: translateX(-50%);
            background-color: rgba(255, 255, 255, 0.7);
            padding: 20px;
            border-radius: 15px;
            text-align: center;
            font-size: 17px;
            color: #444;
            width: 80%;
            max-width: 600px;
            box-shadow: 0 8px 15px rgba(0, 0, 0, 0.3);
            animation: fadeIn 1s ease-in-out;
        }

        @media (max-width: 480px) {
            .container {
                padding: 20px;
                width: 90%;
            }

            h1 {
                font-size: 24px;
            }

            p {
                font-size: 16px;
            }

            a {
                font-size: 14px;
            }

            .text-overlay {
                font-size: 16px;
                width: 90%;
            }
        }
    </style>
</head>
<body>
<!-- 新增的文字容器 -->
<div class="text-overlay">
    ROY6住在一个未知的BAOBAO森林里,<br>
    它们喜欢音乐、舞蹈,还喜欢用自己被赋予的神秘力量,帮助地球上的人们。<br>
    如果你忽然感到幸福,不再孤单,那是因为ROY6来到了你身边!<br>
    在日常生活中,当你想要获得小小的幸运时,就请呼叫ROY6吧!
</div>

<div class="container">
    <h1>${username} 欢迎来到ROY6!</h1>
    <p>请选择您想进行的操作:</p>
    <a href="${pageContext.request.contextPath}/add">新增Roy6商品</a>
    <a href="${pageContext.request.contextPath}/list">查看Roy6商品</a>
</div>
</body>
</html>

8、相关配置

(1)web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

(2)lib包

这里因为我用的是 Tomcat10.0.23 的版本,所以使用了6.0的 jar 包,大家使用对应自己的就行,或者采用Maven配置

(3)spring配置(applicationContext.xml)

创建配置文件applicationContext.xml,在该文件中配置id为dataSource的数据源Bean和id为jdbcTemplate的JDBC模板Bean,并将数据源注入到JDBC模板中。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!-- Enable Spring MVC components and default configuration -->
    <mvc:annotation-driven />

    <!-- Scan for components (controllers, services, repositories) in the specified package -->
    <context:component-scan base-package="com.example.demo" />
    <context:component-scan base-package="com.example.demo.controller"/>

    <!-- 视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!-- 前缀 -->
        <property name="prefix" value="/WEB-INF/views/" />
        <!-- 后缀 -->
        <property name="suffix" value=".jsp" />
    </bean>

    <!-- DataSource configuration for connecting to MySQL database -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/spring_db?useUnicode=true characterEncoding=UTF-8 useSSL=false serverTimezone=UTC" />
        <property name="username" value="root" />
        <property name="password" value="这里写你的数据库密码" />
    </bean>

    <!-- JdbcTemplate bean for database operations -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <bean id="txManage" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
            <property name="transactionManager" ref="txManage"/>
    </bean>

    <bean id="resourceHttpRequestHandler" class="org.springframework.web.servlet.resource.ResourceHttpRequestHandler">
        <property name="locations">
            <list>
                <value>classpath:/static/</value>
            </list>
        </property>
    </bean>
</beans>

9、后端代码

(1)编写Controller层

创建IndexController类,用于实现首页跳转登录注册操作。

IndexController.java
package com.example.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/index")
public class IndexController {
    @RequestMapping(value = "/login",method = RequestMethod.GET)
    public String login(){
        return "login";
    }
    @RequestMapping("/register")
    public String register(){
        return "register";
    }
}

创建IndexController类,用于实现用户登录注册操作。

UserController.java
package com.example.demo.controller;

import com.example.demo.service.UserService;
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 org.springframework.web.servlet.ModelAndView;


@Controller
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/login")

    public String showLoginForm() {
        return "login";
    }

    @PostMapping("/doLogin")
    public ModelAndView login(@RequestParam("username") String username, @RequestParam("password") String password){
        ModelAndView modelAndView = new ModelAndView();
        String result = userService.Login(username,password);
        if("success".equals(result)){
            modelAndView.addObject("username",username);
            modelAndView.setViewName("welcome"); //设置视图为welcome.jsp
        }else{
            modelAndView.addObject("error",true);
            modelAndView.setViewName("login");

        }
        return modelAndView;
    }


    @GetMapping("/register")
    public String showRegisterForm(){
        return "register";
    }

    @PostMapping("/doRegister")
    public ModelAndView Register(@RequestParam("username") String username, @RequestParam("password") String password, @RequestParam("confirmPassword") String confirmPassword) {
        ModelAndView modelAndView = new ModelAndView();
        if (!confirmPassword.equals(password)) {
            modelAndView.addObject("error", "两次密码不一致");
            modelAndView.setViewName("register");  // 返回注册页面
            return modelAndView;
        }
        try {
            userService.Register(username, password);
            modelAndView.setViewName("success"); // 注册成功后跳转到success.jsp页面
            modelAndView.addObject("username", username);
        } catch (IllegalArgumentException e) {
            modelAndView.addObject("error", "注册失败,用户名已存在");
            modelAndView.setViewName("register"); // 注册失败,仍然在注册页面
        }
        return modelAndView;
    }

}

(2)编写Dao层方法

创建UsersDAO接口,在UsersDAO接口中声明查询所有用户信息和更新的方法。

UsersDAO.java
package com.example.demo.dao;

import com.example.demo.model.Users;

import java.util.List;

public interface UsersDAO {
    public int update(String sql, Object[] params);
    public List<Users> query(String sql, Object[] params);
}

(3)实现Dao层方法

创建UsersDAOImpl实现类,在UsersDAOImpl类中实现UsersDAO接口中的 update() 和 query() 方法。

UsersDAOImpl.java
package com.example.demo.dao;

import com.example.demo.model.Users;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public class UsersDAOImpl implements UsersDAO {  // 加上 implements UsersDAO

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public int update(String sql, Object[] params) {
        return jdbcTemplate.update(sql, params);
    }

    @Override
    public List<Users> query(String sql, Object[] params) {
        RowMapper<Users> rowMapper = new BeanPropertyRowMapper<>(Users.class);
        return jdbcTemplate.query(sql, rowMapper, params);
    }
}

(4)编写实体类

创建Users类,在该类中定义username、password属性,以及属性对应的getter/setter方法。

Users.java
package com.example.demo.model;

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

    public String getName() {
        return username;
    }

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

    public String getPassword() {
        return password;
    }

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

(5)编写服务层接口

创建UserService接口,在UserService接口中声明登录和注册的方法。

UserService.java
package com.example.demo.service;

public interface UserService {
    public String Login(String username, String password);

    public void Register(String username, String password);
}

(6)实现服务层方法

创建UserServiceImpl实现类,在UserServiceImpl类中实现UserService接口中的 Login() 和 Register() 方法。

UserServiceImpl.java
package com.example.demo.service;

import com.example.demo.dao.UsersDAO;
import com.example.demo.model.Users;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UsersDAO usersDAO;

    @Override
    public String Login(String username, String password) {
        // 使用占位符避免SQL注入
        String sql = "SELECT * FROM user WHERE username = ? AND password = ?";
        List<Users> users = usersDAO.query(sql, new Object[]{username, password});
        if (!users.isEmpty()) {
            return "success";
        }
        return "login?error=true";
    }

    @Override
    public void Register(String username, String password) {
        String checkUserSql = "SELECT * FROM user WHERE username = ?";
        List<Users> existingUsers = usersDAO.query(checkUserSql, new Object[]{username});
        if (!existingUsers.isEmpty()) {
            throw new IllegalArgumentException("Username already exists");
        }
        String insertUserSql = "INSERT INTO user (username, password) VALUES (?, ?)";
        usersDAO.update(insertUserSql, new Object[]{username, password});
    }
}

10、 查看运行结果

运行结果当然在上边就展示了哈哈哈,会遇到同样喜欢Roy6家族的友友嘛~嘻嘻~

哈哈,到这里就结束了~

码字不易,别忘记 点赞收藏哦!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2246676.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

用 React18 构建点击计分小游戏

本教程将带你创建一个简单的点击计分游戏&#xff0c;使用 React 和基本的 Hooks。游戏规则很简单&#xff1a;在 10 秒内尽可能多地点击按钮以获取高分。 项目结构 确保你的项目结构如下&#xff1a; 编写 ClickGame 组件 在 src/ClickGame.js 文件中&#xff0c;编写如下…

Halo 正式开源: 使用可穿戴设备进行开源健康追踪

在飞速发展的可穿戴技术领域&#xff0c;我们正处于一个十字路口——市场上充斥着各式时尚、功能丰富的设备&#xff0c;声称能够彻底改变我们对健康和健身的方式。 然而&#xff0c;在这些光鲜的外观和营销宣传背后&#xff0c;隐藏着一个令人担忧的现实&#xff1a;大多数这些…

数据结构:链表进阶

链表进阶 1. ArrayList的缺陷2. 链表2.1 链表的概念及结构2.2 链表的实现 3.链表面试题4.LinkedList的使用5.1 什么是LinkedList4.2 LinkedList的使用 5. ArrayList和LinkedList的区别 1. ArrayList的缺陷 通过源码知道&#xff0c;ArrayList底层使用数组来存储元素&#xff1…

第二十二周机器学习笔记:动手深度学习之——线性代数

第二十周周报 摘要Abstract一、动手深度学习1. 线性代数1.1 标量1.2 向量1.3 矩阵1.4 张量1.4.1 张量算法的基本性质 1.5 降维1.5.1 非降维求和 1.6 点积1.6.1 矩阵-向量积1.6.2 矩阵-矩阵乘法 1.7 范数 总结 摘要 本文深入探讨了深度学习中的数学基础&#xff0c;特别是线性代…

Flink-Source的使用

Data Sources 是什么呢&#xff1f;就字面意思其实就可以知道&#xff1a;数据来源。 Flink 做为一款流式计算框架&#xff0c;它可用来做批处理&#xff0c;也可以用来做流处理&#xff0c;这个 Data Sources 就是数据的来源地。 flink在批/流处理中常见的source主要有两大类…

分公司如何纳税

分公司不进行纳税由总公司汇总纳税“子公司具有法人资格&#xff0c;依法独立承担民事责任;分公司不具有法人资格&#xff0c;其民事责任由公司承担。”企业设立分支机构&#xff0c;使其不具有法人资格&#xff0c;且不实行独立核算&#xff0c;则可由总公司汇总缴纳企业所得税…

亚马逊搜索关键词怎么写?

在亚马逊这个全球领先的电子商务平台&#xff0c;如何让自己的产品被更多的消费者发现&#xff0c;是每一个卖家都需要深入思考的问题。而搜索关键词&#xff0c;作为连接卖家与买家的桥梁&#xff0c;其重要性不言而喻。那么&#xff0c;如何撰写有效的亚马逊搜索关键词呢&…

跨视角差异-依赖网络用于体积医学图像分割|文献速递-生成式模型与transformer在医学影像中的应用

Title 题目 Cross-view discrepancy-dependency network for volumetric medical imagesegmentation 跨视角差异-依赖网络用于体积医学图像分割 01 文献速递介绍 医学图像分割旨在从原始图像中分离出受试者的解剖结构&#xff08;例如器官和肿瘤&#xff09;&#xff0c;并…

基本功能实现

目录 1、环境搭建 2、按键控制灯&电机 LED 电机 垂直按键(机械按键) 3、串口调试功能 4、定时器延时和定时器中断 5、振动强弱调节 6、万年历 7、五方向按键 1、原理及分析 2、程序设计 1、环境搭建 需求: 搭建一个STM32F411CEU6工程 分析: C / C 宏定义栏…

C++11新特性探索:Lambda表达式与函数包装器的实用指南

文章目录 前言&#x1f349;一、Lambda表达式&#xff08;匿名函数&#xff09;&#x1f353;1.1 Lambda 表达式的基本语法&#x1f353;1.2 示例&#xff1a;基本 Lambda 表达式&#x1f353;1.3 捕获列表&#xff08;Capture&#xff09;&#x1f353;1.4 使用 Lambda 表达式…

msvcp110.dll丢失修复的多种科学方法分析,详细解析msvcp110.dll文件

遇到“msvcp110.dll丢失”的错误时&#xff0c;这表明你的系统缺少一个关键文件&#xff0c;但解决这一问题比较直接。本文将指导你通过几个简单的步骤迅速修复此错误&#xff0c;确保你的程序或游戏可以顺利运行。接下来的操作将非常简洁明了&#xff0c;易于理解和执行。 一.…

HDR视频技术之四:HDR 主要标准

HDR 是 UHD 技术中最重要维度之一&#xff0c;带来新的视觉呈现体验。 HDR 技术涉及到采集、加工、传输、呈现等视频流程上的多个环节&#xff0c;需要定义出互联互通的产业标准&#xff0c;以支持规模化应用和部署。本文整理当前 HDR 应用中的一些代表性的国际标准。 1 HDR 发…

Bug Fix 20241122:缺少lib文件错误

今天有朋友提醒才突然发现 gitee 上传的代码存在两个很严重&#xff0c;同时也很低级的错误。 因为gitee的默认设置不允许二进制文件的提交&#xff0c; 所以PH47框架下的库文件&#xff08;各逻辑层的库文件&#xff09;&#xff0c;以及Stm32Cube驱动的库文件都没上传到Gi…

c++源码阅读__smart_ptr__正文阅读

文章目录 简介源码解析1. 引用计数的实现方式2. deleter静态方法的赋值时间节点3.make_smart的实现方式 与 好处4. 几种构造函数4.1 空构造函数4.2 接收指针的构造函数4.3 接收指针和删除方法的构造函数 , 以及auto进行模板lambda的编写4.4 拷贝构造函数4.5 赋值运算符 5. rele…

【BUG】ES使用过程中问题解决汇总

安装elasticsearch内存不足问题 问题回顾 运行kibana服务的时候&#xff0c;无法本地访问 解决 首先排查端口问题&#xff0c;然后检查错误日志 无法运行kibana服务&#xff0c;是因为elasticsearch没有启动的原因 发现致命错误&#xff0c;确定是elasticsearch服务没有运行导…

C语言--分支循环编程题目

第一道题目&#xff1a; #include <stdio.h>int main() {//分析&#xff1a;//1.连续读取int a 0;int b 0;int c 0;while (scanf("%d %d %d\n", &a, &b, &c) ! EOF){//2.对三角形的判断//a b c 等边三角形 其中两个相等 等腰三角形 其余情…

Linux——用户级缓存区及模拟实现fopen、fweite、fclose

linux基础io重定向-CSDN博客 文章目录 目录 文章目录 什么是缓冲区 为什么要有缓冲区 二、编写自己的fopen、fwrite、fclose 1.引入函数 2、引入FILE 3.模拟封装 1、fopen 2、fwrite 3、fclose 4、fflush 总结 前言 用快递站讲述缓冲区 收件区&#xff08;类比输…

git(Linux)

1.git 三板斧 基本准备工作&#xff1a; 把远端仓库拉拉取到本地了 .git --> 本地仓库 git在提交的时候&#xff0c;只会提交变化的部分 就可以在当前目录下新增代码了 test.c 并没有被仓库管理起来 怎么添加&#xff1f; 1.1 git add test.c 也不算完全添加到仓库里面&…

GESP2023年9月认证C++四级( 第三部分编程题(1-2))

编程题1&#xff08;string&#xff09;参考程序&#xff1a; #include <iostream> using namespace std; long long hex10(string num,int b) {//int i;long long res0;for(i0;i<num.size();i) if(num[i]>0&&num[i]<9)resres*bnum[i]-0;else //如果nu…

Ultiverse 和web3新玩法?AI和GameFi的结合是怎样

Gamef 和 AI 是我们这个周期十分看好两大赛道之一&#xff0c;(Gamef 拥有极强的破圈效应&#xff0c;引领 Web2 用户进军 Web3 最佳利器。AI是这个周期最热门赛道&#xff0c;无论 Web2的 OpenAl&#xff0c;还是 Web3&#xff0c;都成为话题热议焦点。那么结合 GamefiA1双叙事…