零基础做项目---五子棋对战---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%2B8username: rootpassword: 密码driver-class-name: com.mysql.cj.jdbc.Drivermybatis:mapper-locations: classpath:mapper/**Mapper.xmllogging: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 {@Autowiredprivate UserMapper userMapper;@PostMapping("/login")@ResponseBodypublic 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")@ResponseBodypublic Object register(String username, String password) {try {User user = new User();user.setUsername(username);user.setPassword(password);//天梯分数新手默认1200user.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")@ResponseBodypublic 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>

注册功能验证

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

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

相关文章

【ffmpeg系列二点五】(失败,建议放弃)ubuntu下进行源码构建,给ffmpeg7.0.1添加hevc支持。

背景 windows下构建失败&#xff0c;ffmpeg对于flv-h265的处理得到新的报错。 开始ubuntu22下编译 pre&#xff1a;清除我们之前编译的nightly版本 sudo rm -rf /usr/local/bin/ffmpeg sudo rm -rf /usr/local/bin/ffprobe sudo rm -rf /usr/local/bin/ffserver sudo rm -…

轻松掌握图片压缩技巧,释放存储空间!

前言 在这个充满视觉冲击的时代&#xff0c;我们每天都在创造和分享图片。但你是否发现&#xff0c;手机和电脑的存储空间越来越不够用了&#xff1f;图片文件过大&#xff0c;不仅占用空间&#xff0c;还影响传输速度和网页加载。今天&#xff0c;就让我来教你几招&#xff0…

Python爬虫:BeautifulSoup的基本使用方法!

1.简介 Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析“标签树”等功能。它是一个工具箱&#xff0c;通过解析文档为用户提供需要抓取的数据&#xff0c;因为简单&#xff0c;所以不需要多少代码就可以写出一个完整的应用程序。 Beautiful Soup…

Python基础语法:变量和数据类型详解(整数、浮点数、字符串、布尔值)①

文章目录 变量和数据类型详解&#xff08;整数、浮点数、字符串、布尔值&#xff09;一、变量二、数据类型1. 整数&#xff08;int&#xff09;2. 浮点数&#xff08;float&#xff09;3. 字符串&#xff08;str&#xff09;4. 布尔值&#xff08;bool&#xff09; 三、类型转换…

生物打印后的生物力学过程

生物打印后的生物力学过程 3D生物打印技术在组织工程领域展现出巨大的潜力&#xff0c;但打印后组织的生物力学特性对其最终成功至关重要。本文将详细介绍打印后组织的生物力学特性及其在组织工程中的应用。 1. 打印后水凝胶交联 原位交联可以在生物打印过程中提供足够的机械…

LoRaWAN网络协议Class A/Class B/Class C三种工作模式说明

LoRaWAN是一种专为广域物联网设计的低功耗广域网络协议。它特别适用于物联网&#xff08;IoT&#xff09;设备&#xff0c;可以在低数据速率下进行长距离通信。LoRaWAN 网络由多个组成部分构成&#xff0c;其中包括节点&#xff08;终端设备&#xff09;、网关和网络服务器。Lo…

【Unity2D 2022:NPC】制作任务系统

一、接受任务 1. 编辑NPC对话脚本&#xff1a; &#xff08;1&#xff09;创建静态布尔变量用来判断ruby是否接受到任务 public class NPCDialog : MonoBehaviour {// 创建全局变量用来判断ruby是否接到任务public static bool receiveTask false; } &#xff08;2&#xff…

类型“RouteRecordName”上不存在属性“includes”。 类型“symbol”上不存在属性“includes”

确定 route.name 运行时是 字符串&#xff0c;强制转换 为字符串。 removeRoute(id: string) { this.dynamRoute this.dynamRoute.filter(route > !(route.name as string).includes(id)) localStorage.setItem(dynamRoute, JSON.stringify(this.dynamRoute)) delete this.t…

4.3 设备管理

大纲 设备分类 输入输出 虚设备和SPOOLING技术

【C语言之高级编程】如何将指定变量或函数编译至固定的内存区域中?

如何将指定变量或函数编译至固定的内存区域&#xff1f; 1. 内存类型1.1 bss段&#xff08;Block Started by Symbol&#xff09;1.2 data段&#xff08;data segment&#xff09;1.3 text段&#xff08;code segment/text segment&#xff09;1.4 dec1.5 堆&#xff08;heap&a…

绝区玖--人工智能物料清单 (AI BOM)

前言 AI BOM 涵盖了从输入模型的数据到为模型提供支持的基础设施以及将 AI 从概念转化为生产的过程的一切。 但为什么我们需要人工智能物料清单&#xff1f;答案在于当今世界人工智能/Gen AI系统的复杂性和关键性&#xff1a; 透明度和可重复性&#xff1a;AI BOM 提供所有组件…

python怎么求因数

要想做到python语言求因数方法&#xff0c;首先要明白其中的原理&#xff1a; 1、对由123456789这九个数字组成的9位数进行分解质因数。 2、1234576982x3x3x7x13x23x29x113&#xff0c;所以他的值因数是113。 3、总共有362880种可能&#xff0c;从中找出值因数中最小的数字和…

动态规划算法专题二--路径问题

目录 专题二&#xff1a; 路径问题 题五 不同路径 1、算法解析 1、确定状态&#xff1a; 2、状态转移方程&#xff1a; 3、初始化&#xff1a; 4、填表顺序&#xff1a; 5、返回值&#xff1a; 2、代码 题六 不同路径II 1、算法解析 1、确定状态&#xff1a; 2、状态…

前端面试题(CSS篇六)

一、浏览器如何判断是否支持 webp 格式图片 &#xff08;1&#xff09;宽高判断法。通过创建image对象&#xff0c;将其src属性设置为webp格式的图片&#xff0c;然后在onload事件中获取图片的宽高&#xff0c;如果能够获取&#xff0c;则说明浏览器支持webp格式图片。如果不能…

Qt:13.多元素控件(QLinstWidget-用于显示项目列表的窗口部件、QTableWidget- 用于显示二维数据表)

目录 一、QLinstWidget-用于显示项目列表的窗口部件&#xff1a; 1.1QLinstWidget介绍&#xff1a; 1.2属性介绍&#xff1a; 1.3常用方法介绍&#xff1a; 1.4信号介绍&#xff1a; 1.5实例演示&#xff1a; 二、QTableWidget- 用于显示二维数据表&#xff1a; 2.1QTabl…

Vue学习笔记(小满zs)

本文章记录一下我的学习笔记&#xff0c;供复习参考。&#x1f3c6; 向大佬学习&#xff01;&#xff01;&#xff01; ⭐小满zs Nodejs Nodejs 三层组成 libuv&#xff08;处理事件循环、I/O操作&#xff09; 第三方库&#xff08;处理HTTP等&#xff09; V8引擎&#xff08…

Windows10系统下mysql5.6的安装步骤

1.下载mysql 下载地址&#xff1a;https://downloads.mysql.com/archives/community/ 在这里我们下载zip的包 2.解压mysql包到指定目录 3. 添加my.ini文件 # For advice on how to change settings please see # http://dev.mysql.com/doc/refman/5.6/en/server-configurat…

【欧美高端NFT链游--大嘴怪/小黄人】链游

#游戏#链游 呆萌的小黄人出现在大嘴怪的地盘上会发生什么有趣的事情呢?#动画#游戏#小黄人 大嘴怪与小黑人之间起了冲突&#xff0c;大嘴怪爆发了&#xff0c;他决定要给小黑人们一点颜色瞧瞧&#xff0c;用自己的拳头&#xff0c;以及&#xff1f;?嘴巴&#xff01;大嘴怪有…

视频号的视频,一键就下载了,方法全在这儿了!

居然还有人不知道&#xff1a;视频号里面的视频是没有地址的&#xff0c;只能有微信自带的浏览器中打开。 所以很多人在视频号找到想要的素材&#xff0c;却无法下载&#xff0c;表示很苦恼。 几天每天都有人群里求助&#xff1a;“求好心人帮我下载一下这个视频&#xff01;…

漏洞挖掘 | 记某证书站任意账号接管漏洞

下文中所述漏洞已修复 在前段时间的漏洞挖掘中&#xff0c;上了某证书站&#xff0c;打点的一处逻辑漏洞 访问某一站点&#xff0c;发现了一处登录页 点击登录按钮之后&#xff0c;发现该站点大概率是自写站点&#xff0c;存在逻辑漏洞的可能性大大增大&#xff0c;利用前期信…