零基础做项目---五子棋对战---day02

用户模块

完成注册登录,以及用户分数管理~使用数据库来保存上述用户信息.

使用 MyBatis来连接并操作数据库了

主要步骤: 

1.修改 Spring的配置文件,使数据库可以被连接上.

2.创建实体类,用户, User

3.创建Mapper接口~

4.实现MyBatis 的相关xml配置文件,来自动的实现数据库操作

修改Spring的配置文件

将application.properties重命名为application.yml, 粘贴代码

yml代码:

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/java_gobang?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
    username: root
    password: 密码
    driver-class-name: com.mysql.cj.jdbc.Driver

mybatis:
  mapper-locations: classpath:mapper/**Mapper.xml

logging:
  pattern:
    console: "[%-5level] - %msg%n"

创建数据库

创建数据库并且插入数据

create database if not exists java_gobang;

use java_gobang;
drop table if exists user;
create table user (
    userId int primary key auto_increment,
    username varchar(50) unique,
    password varchar(50),
    score int, -- 天梯积分
    totalCount int, -- 比赛总场数
    winCount int -- 获胜场数
);

insert into user values (null, '张雨潇', '123', 1000, 0, 0);
insert into user values (null, '李明', 'password1', 1200, 10, 6);
insert into user values (null, '王芳', 'password2', 1100, 8, 4);
insert into user values (null, '刘强', 'password3', 950, 12, 5);
insert into user values (null, '赵静', 'password4', 980, 7, 3);
insert into user values (null, '孙鹏', 'password5', 1050, 11, 7);
insert into user values (null, '周丽', 'password6', 1020, 9, 4);
insert into user values (null, '郑凯', 'password7', 1150, 15, 8);
insert into user values (null, '何敏', 'password8', 990, 10, 5);
insert into user values (null, '吴昊', 'password9', 1080, 13, 6);
insert into user values (null, '陈晓', 'password10', 930, 8, 3);
insert into user values (null, '杨洋', 'password11', 1120, 14, 9);
insert into user values (null, '林静', 'password12', 1040, 11, 6);
insert into user values (null, '张伟', 'password13', 950, 7, 2);
insert into user values (null, '刘畅', 'password14', 1070, 12, 7);
insert into user values (null, '宋雨', 'password15', 990, 9, 4);
insert into user values (null, '唐鹏', 'password16', 1010, 10, 5);
insert into user values (null, '许娟', 'password17', 920, 6, 2);
insert into user values (null, '高飞', 'password18', 960, 8, 3);
insert into user values (null, '钟丽', 'password19', 980, 7, 3);
insert into user values (null, '魏强', 'password20', 1100, 10, 5);

命令行运行即可

约定前后端交互接口

登录接口

  • 请求
    POST /login HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    username=zhangsan&password=123
    

  • 响应
    HTTP/1.1 200 OK
    Content-Type: application/json
    {
      "userId": 1,
      "username": "zhangsan",
      "score": 1000,
      "totalCount": 0,
      "winCount": 0
    }
    
    如果登录失败,返回一个无效的用户对象,每个属性为空或为默认值,例如 userId=0
    

    注册接口

  • 请求
    POST /register HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    username=zhangsan&password=123
    

  • 响应
    HTTP/1.1 200 OK
    Content-Type: application/json
    {
      "userId": 1,
      "username": "zhangsan",
      "score": 1000,
      "totalCount": 0,
      "winCount": 0
    }
    

    获取用户信息接口

  • 请求
    GET /userInfo HTTP/1.1
    
     
  • 响应
    HTTP/1.1 200 OK
    Content-Type: application/json
    {
      "userId": 1,
      "username": "zhangsan",
      "score": 1000,
      "totalCount": 0,
      "winCount": 0
    }
    

编写用户实体

package com.example.java_gobang.model;

public class User {
    private int userId;
    private String username;
    private String password;
    private int score;
    private int totalCount;
    private int winCount;

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

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

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

    public int getTotalCount() {
        return totalCount;
    }

    public void setTotalCount(int totalCount) {
        this.totalCount = totalCount;
    }

    public int getWinCount() {
        return winCount;
    }

    public void setWinCount(int winCount) {
        this.winCount = winCount;
    }
}

创建Mapper接口

UserMapper.xml

<?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">
<mapper namespace="com.example.java_gobang.model.UserMapper">
    <insert id="insert">
        insert into user values (null, #{username}, #{password}, 1000, 0, 0);
    </insert>

    <select id="selectByName" resultType="com.example.java_gobang.model.User">
        select * from user where username = #{username};
    </select>

</mapper>

UserMapper

package com.example.java_gobang.model;

import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper {
    //插入一个用户, 用于注册功能
    void insert(User user);

    //根据用户名, 来查询用户的详细信息, 用于登录
    User selectByName(String username);
}

UserAPI

package com.example.java_gobang.api;

import com.example.java_gobang.model.User;
import com.example.java_gobang.model.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

@RestController
public class UserAPI {
    @Autowired
    private UserMapper userMapper;
    @PostMapping("/login")
    @ResponseBody
    public Object login(String username, String password, HttpServletRequest request) {
        //关键操作: 根据username去数据库查询
        // 如果能找到匹配的用户并且密码一致, 就确认为登陆成功
        User user = userMapper.selectByName(username);
        if (user == null || !user.getPassword().equals(password)) {
            return new User(); //这是空对象 说明登录失败
        }
        //这里的true表示如果会话存在, 那么返回session, 不存在创建一个新的会话返回
        HttpSession httpSession = request.getSession(true);
        httpSession.setAttribute("user", user);
        return user;
    }
    @PostMapping("/register")
    @ResponseBody
    public Object register(String username, String password) {
        try {
            User user = new User();
            user.setUsername(username);
            user.setPassword(password);
            //天梯分数新手默认1200
            user.setScore(1200);
            user.setWinCount(0);
            user.setTotalCount(0);
            userMapper.insert(user);
            return user;
        } catch (org.springframework.dao.DuplicateKeyException e) {
            //key重复异常
            User user = new User();
            return user;
        }

    }
    @PostMapping("/userInfo")
    @ResponseBody
    public Object getUserInfo(HttpServletRequest request) {
        try {
            HttpSession httpSession = request.getSession(false);
            User user = (User) httpSession.getAttribute("user");
            return user;
        } catch (NullPointerException e) {
            return new User();
        }
    }
}

其中有登录, 注册, 查询用户信息的方法

其中@PostMapping("/register"):映射HTTP POST请求到/register路径。

会话机制讲解

request.getSession(true)
  • 功能getSession(true)方法会检查当前请求是否已经有一个会话。如果有,会返回这个会话。如果没有,它会创建一个新的会话并返回。
  • 参数true:表示如果没有现有的会话,创建一个新的会话。
HttpSession
  • 会话对象HttpSession是一个接口,提供了一种在多个请求中标识用户的方法,并且能够存储用户会话期间的信息。典型的用法包括存储用户的登录状态、购物车内容等。
httpSession.setAttribute("user", user)
  • 设置属性setAttribute方法用于在会话中存储一个键值对。这里的键是"user",值是用户对象user
  • 作用:将当前登录的用户信息存储到会话中,以便在后续的请求中可以方便地获取到用户信息。

登录注册的前端页面

登录的html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
    <div class="nav">
        五子棋对战
    </div>
    
    <div class="login-container">
        <!-- 登录界面对话框 -->
        <div class="login-dialog">
            <h3>登录</h3>
            <!-- 这个表示一行 输入用户名的一行 -->
            <div class="row">
                <span>用户名</span>
                <input type="text" id="username">
            </div>
            <!-- 这个表示一行 输入密码的一行 -->
            <div class="row">
                <span>密码</span>
                <input type="password" id="password">
            </div>
            <!-- 提交按钮 -->
            <button id="submit">提交</button>
        </div>
    </div>
</body>
</html>

common.css和login.css

/* 公共的样式 */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

/* 设置图片能够覆盖全部窗口 */
html, body {
    height: 100%;
    background-image: url(../image/background.jpg);
    background-repeat: no-repeat;
    background-position: center;
    background-size: cover;
}

.nav {
    height: 50px;
    background-color: rgb(50, 50, 50);
    color: aliceblue;
    line-height: 50px;
    padding-left: 20px;
}

login.css

.login-container {
    height: calc(100% - 50px);
    display: flex;
    justify-content: center;
    align-items: center;
}

.login-dialog {
    width: 400px;
    height: 400px;
    background-color: rgba(255, 255, 255, 0.8);
    border-radius: 10px;
}

/* 标题 */
.login-dialog h3 {
    text-align: center;
    padding: 50px 0;
}

/* 针对一行设置样式 */
.login-dialog .row {
    width: 100%;
    height: 50px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.login-dialog .row span {
    width: 100px;
    font-weight: 700;
}

#username, #password {
    width: 200px;
    height: 40px;
    font-size: 20px;
    line-height: 40px;
    padding-left: 10px;
    border: none;
    outline: none;
    border-radius: 10px;
}

.button-container {
    display: flex;
    justify-content: center;
}

#submit {
    width: 300px;
    height: 50px;
    background-color: rgb(0, 128, 0);
    color: white;
    border: none;
    outline: none;
    border-radius: 10px;
    margin-top: 20px;
}

#submit:active {
    background-color: #666;
}

/* 公共的样式 */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

/* 设置图片能够覆盖全部窗口 */
html, body {
    height: 100%;
    background-image: url(../image/background.jpg);
    background-repeat: no-repeat;
    background-position: center;
    background-size: cover;
}

.nav {
    height: 50px;
    background-color: rgb(50, 50, 50);
    color: aliceblue;
    line-height: 50px;
    padding-left: 20px;
}

引入jQuery

百度搜索 jQuery cdn

比如使用字节的

https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/1.7.2/jquery.min.js

全选保存

引入:

<script src="./js/jquery.min.js"></script>

处理登录的代码

<script>
        let usernameInput = document.querySelector('#username');
        let passwordInput = document.querySelector('#password');
        let submitButton = document.querySelector('#submit');
        submitButton.onclick = function() {
            // 禁用提交按钮,避免重复提交
            submitButton.disabled = true;
            $.ajax({
                type: 'post',
                url: '/login',
                data: {
                    username: usernameInput.value,
                    password: passwordInput.value,
                },
                success: function(body) {
                    // 请求执行成功之后的回调函数
                    // 判定当前是否登录成功~
                    // 如果登录成功, 服务器会返回当前的 User 对象.
                    // 如果登录失败, 服务器会返回一个空的 User 对象.
                    if (body && body.userId > 0) {
                        // 登录成功
                        alert("登录成功!");
                        // 重定向跳转到 "游戏大厅页面".
                        location.assign('/game_hall.html');
                    } else {
                        alert("登录失败!, 请检查密码是否正确");
                    }
                },
                error: function() {
                    // 请求执行失败之后的回调函数
                    alert("登录失败!");
                },
                complete: function() {
                    //AJAX请求完成后重新启用按钮
                    submitButton.disabled = false;
                }
            });
        }
    </script>

验证登录页面

启动服务器

访问 http://127.0.0.1:8080/login.html

注册样式

与登录大差不差


    <div class="nav">
        五子棋对战
    </div>
    <div class="login-container">
        <!-- 登录界面的对话框 -->
        <div class="login-dialog">
            <!-- 提示信息 -->
            <h3>注册</h3>
            <div class="row">
                <span>用户名</span>
                <input type="text" id="username">
            </div>
            <div class="row">
                <span>密码</span>
                <input type="password" id="password">
            </div>
            <!-- 提交按钮 -->
            <div class="row">
                <button id="submit">提交</button>
            </div>
        </div>
    </div> 

script代码


    <script src="js/jquery.min.js"></script>
    <script>
        let usernameInput = document.querySelector('#username');
        let passwordInput = document.querySelector('#password');
        let submitButton = document.querySelector('#submit');
        submitButton.onclick = function() {
            // 禁用提交按钮,避免重复提交
            submitButton.disabled = true;
            $.ajax({
                type: 'post',
                url: '/register',
                data: {
                    username: usernameInput.value,
                    password: passwordInput.value,
                },
                success: function(body) {
                    // 如果注册成功, 就会返回一个新注册好的用户对象. 
                    if (body && body.username) {
                        // 注册成功!
                        alert("注册成功!")
                        location.assign('/login.html');
                    } else {
                        alert("注册失败!");
                    }
                }, 
                error: function() {
                    alert("注册失败!");
                },
                complete: function() {
                    //AJAX请求完成后重新启用按钮
                    submitButton.disabled = false;
                }
            });
        }

    </script>

注册功能验证

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

微软代码签名证书的申请流程包含哪几个关键步骤?

在软件开发环境中&#xff0c;确保软件的安全性和可信度至关重要。沃通CA提供的代码签名证书作为一种重要的安全措施&#xff0c;可以帮助开发者验证其软件的来源和完整性&#xff0c;有效地避免用户因安全顾虑而避免安装或使用软件。本文将详细介绍如何申请沃通CA代码签名证书…

类与对象-继承-同名成员处理

同名成员处理 #include<iostream> using namespace std;//继承中同名成员处理方式class Base { public:Base(){m_A 100;}void func(){cout << "Base - func()调用" << endl;}void func(int a){cout << "Base - func(int a)调用"…

AI编程工具:豆包 MarsCode 实测

MarsCode 官网&#xff1a;https://docs.marscode.cn/introduction 要提一嘴的是&#xff0c;区别其他 AI 编程助手&#xff0c;豆包 MarsCode 除了提供智能编程助手之外&#xff0c;还提供了一个 AI 原生的云端继承开发环境&#xff08;IDE&#xff09;。 实测下来&#xff…

GOLLIE : ANNOTATION GUIDELINES IMPROVE ZERO-SHOT INFORMATION-EXTRACTION

文章目录 题目摘要引言方法实验消融 题目 Gollie&#xff1a;注释指南改进零样本信息提取 论文地址&#xff1a;https://arxiv.org/abs/2310.03668 摘要 大型语言模型 (LLM) 与指令调优相结合&#xff0c;在泛化到未见过的任务时取得了重大进展。然而&#xff0c;它们在信息提…

高考后暑假新选择:从AI聊天机器人开发入门IT领域

你好&#xff0c;我是三桥君 七月来临&#xff0c;各省高考分数已揭榜完成。而高考的完结并不意味着学习的结束&#xff0c;而是新旅程的开始。对于有志于踏入IT领域的高考少年们&#xff0c;这个假期是开启探索IT世界的绝佳时机。 不知道这些有志于踏入IT领域的高考少年们&…

53-5 内网代理7 - CS上线不出网主机

靶场搭建: 这里就用之前内网代理的靶场,把web服务器这台虚拟机关闭掉,用剩下的3台加kali 各个虚拟机的网络情况 kali - 可以连接外网win2008(之前的FTP服务器) 可以连接外网 win 7(之前的办公电脑) 不出网主机 - 无法连接外网win2012 克隆机(之前的域控) - 无法连接…

AnimateLCM:高效生成连贯真实的视频

视频扩散模型因其能够生成连贯且高保真的视频而日益受到关注。然而&#xff0c;迭代去噪过程使得这类模型计算密集且耗时&#xff0c;限制了其应用范围。香港中文大学 MMLab、Avolution AI、上海人工智能实验室和商汤科技公司的研究团队提出了AnimateLCM&#xff0c;这是一种允…

32位版 C 库函数time 将在 2038 年溢出,那到时候,它该何去何从

简单地说&#xff0c;通常不必担心&#xff0c;在64位操作系统已经成为主流的今天这基本上不是问题&#xff08;在写这篇回答的时候&#xff0c;我才发现我甚至找不到32位的机器来测试&#xff09;刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「32库函数的…

240707-Sphinx配置Pydata-Sphinx-Theme

Step A. 最终效果 Step B. 为什么选择Pydata-Sphinx-Theme主题 Gallery of sites using this theme — PyData Theme 0.15.4 documentation Step 1. 创建并激活Conda环境 conda create -n rtd_pydata python3.10 conda activate rtd_pydataStep 2. 安装默认的工具包 pip in…

Day66 代码随想录打卡|回溯算法篇---分割回文串

题目&#xff08;leecode T131&#xff09;&#xff1a; 给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个子串都是 回文串。返回 s 所有可能的分割方案。 方法&#xff1a;本题是一个分割回文串的问题&#xff0c;是回溯算法的另一类问题。 针对一个字…

溶解氧(DO)理论指南(3)

转载自梅特勒官网资料&#xff0c;仅用于学习交流&#xff0c;侵权则删&#xff01; 溶解氧理论指南 设备操作3.1 DO电极准备3.2 DO电极校准3.3 进行DO测量3.4 转换单位3.5 维护和储存 设备操作 本章总结了 DO电极日常使用的一些建议。它们基于普遍接受的操作规则。 3.1 DO电…

如何在玩客云中安装小雅AList并实现使用手机平板远程连接听歌看电影

文章目录 前言1. 本地部署AList2. AList挂载网盘3. 部署小雅alist3.1 Token获取3.2 部署小雅3.3 挂载小雅alist到AList中 4. Cpolar内网穿透安装5. 创建公网地址6. 配置固定公网地址 前言 本文主要介绍如何在安装了CasaOS的玩客云主机中部署小雅AList&#xff0c;并在AList中挂…

构建高精度室内定位导航系统,从3DGIS到AI路径规划的全面解析

室内定位导航系统是一种利用多种技术实现室内精准定位和导航的智能系统&#xff0c;即便没有卫星信号&#xff0c;也能实现精准导航。维小帮室内定位导航系统是基于自研的地图引擎与先进定位技术&#xff0c;结合智能路径规划算法&#xff0c;解决了人们在大型复杂室内场所最后…

搜维尔科技:【研究】Scalefit是一款可在工作场所自动处理3D姿势分析结果的软件

Scalefit是一款可在工作场所自动处理 3D 姿势分析结果的软件。这甚至可以在衡量员工的同时发生。然后&#xff0c;Scalefit 根据国际标准对姿势、压缩力和关节力矩进行分析和可视化。 3D姿势分析 如今&#xff0c;Xsens 技术可让您快速测量工作场所员工的态度。一套带有 17 个…

【笔记】centos7虚拟机连接dbeaver数据库失败好多次折磨我三天三夜

终于在第四个方法连接上了 你知道这四天三夜我怎么过来的吗 真的好痛苦 一个问题延申了无数个问题到最后我都不记得自己在解决什么问题 Access denied for user xiaoming192.168.81.1 (using password: YES) Public Key Retrieval is not allowed &#xff08;一&#xff09;跳…

高中数学:立体几何-基本立体图形分类

一、常见空间几何体 二、多面体 1、棱柱 2、棱锥 3、棱台 4、相关关系 三、旋转体 1、圆柱 2、圆锥 3、圆台 4、球

新一代iPhone成传家宝,这升级给我看呆了

6 月刚过&#xff0c;数码圈就迎来了平淡期&#xff0c;虽然各家手机层出不穷&#xff0c;但也只是新瓶装旧酒&#xff0c;没啥新意。 翘首以盼的新机也得等到 9 月份才会遍地开花。 这其中让人备受期待的肯定有苹果的一票&#xff0c;而最近苹果新机的消息也渐渐浮出水面了。…

Linux之免费证书工具certbot安装和使用

一、cerbot简介 Certbot是一个免费的开源软件工具&#xff0c;用于在手动管理的网站上自动使用Let’s Encrypt证书以启用HTTPS。要想让自己的网站启用https协议&#xff0c;需要一个由CA&#xff08;数字证书认证机构&#xff09;颁发的&#xff0c;能够让各个浏览器都能承认的…

AIGC在创意设计中的应用

随着人工智能技术的不断进步&#xff0c;AIGC&#xff08;人工智能生成内容&#xff09;已成为创意设计领域的新宠。这种新兴技术以其强大的创作能力和高效的工作效率&#xff0c;正逐渐改变着设计师们的工作方式和创作流程。在这个变革的时代&#xff0c;设计师们纷纷拥抱AIGC…

英伟达今年在华销售额预计将达120亿美元、MiniMax创始人:三年后才会出现“杀手级”AI应用

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 更多资源欢迎关注 1、英伟达今年在华销售额预计将达120亿美元 芯片咨询公司SemiAnalysis报告预估&#xff0c;今年英伟达有望在中国销售价值约120亿美元的人工智能芯片。黄仁勋曾表示&#xff0c;希望借助新的芯片使得…