使用Springboots完成一个登陆网站
使用Springboots完成一个登陆网站
首先,先从老k手里抢一个前端html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>简约登录 / 注册</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
*{box-sizing:border-box;margin:0;padding:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif}
body{background:#f5f5f5;display:flex;align-items:center;justify-content:center;height:100vh}
.card{background:#fff;border-radius:8px;box-shadow:0 4px 12px rgba(0,0,0,.08);width:320px;padding:32px 24px}
h2{text-align:center;margin-bottom:24px;color:#333}
input{width:100%;padding:12px 14px;margin-bottom:16px;border:1px solid #ddd;border-radius:4px;font-size:14px}
button{width:100%;padding:12px;background:#007bff;color:#fff;border:none;border-radius:4px;font-size:14px;cursor:pointer}
button:hover{background:#0069d9}
.tip{color:#666;font-size:13px;text-align:center;cursor:pointer}
.tip span{color:#007bff}
.hidden{display:none}
</style>
<script src="index.js"></script>
</head>
<body>
<!-- 登录 -->
<div class="card" id="loginBox">
<h2>登录</h2>
<input type="text" id="loginUsername" placeholder="用户名" required>
<input type="password" id="loginPwd" placeholder="密码" required>
<button onclick="login()">登录</button>
<p class="tip">没有账号?<span onclick="toggleBox()">立即注册</span></p>
</div>
<!-- 注册 -->
<div class="card hidden" id="regBox">
<h2>注册</h2>
<input type="text" id="registerUsername" placeholder="用户名" required>
<input type="password" id="registerPwd" placeholder="密码 ≥6 位" required>
<input type="password" id="registerPwdConfirm" placeholder="确认密码" required>
<button onclick="register()">注册</button>
<p class="tip">已有账号?<span onclick="toggleBox()">立即登录</span></p>
</div>
好,我们网页完成了,那下班!!!!!
开个玩笑,还登不上去咋下班,产品经理棺材板压不住啦
function login() {
const username = document.getElementById('loginUsername').value;
const password = document.getElementById('loginPwd').value;
if (!username || !password) {
alert('请输入用户名和密码');
return;
}
}
function register() {
const username = document.getElementById('registerUsername').value;
const password = document.getElementById('registerPwd').value;
const passwordConfirm = document.getElementById('registerPwdConfirm').value;
if (!username || !password || !passwordConfirm) {
alert('请输入用户名和密码');
return;
}
if (password !== passwordConfirm) {
alert('两次密码不一致');
return;
}
if (password.length <= 6) {
alert('密码不能少于6位');
return;
}
}
先完成js的本地校验,为了避免多次请求,和精简代码,判断空和相等这种都是在前段完成的
好啦我们确定完需要一个账户一个密码那来写sql结构吧
创建一个名为spring数据库
执行如下sql语句
CREATE TABLE user (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(100),
password VARCHAR(100),
PRIMARY KEY (id)
);
接下来修改yml
把数据库名换成spring
然后在项目文件夹中创建entity文件夹
这个文件夹用来创建对象
创建user类 代码如下
package com.example.spring.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data//自动生成getset方法
@AllArgsConstructor//自动生成全参构造
@NoArgsConstructor//自动生成无参构造
public class user {
private Integer id;
private String name;
private String password;
}
然后在resources中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.spring.mapper.UserMapper">
<resultMap id="BaseResultMap" type="com.example.spring.entity.user">
<id property="id" column="id" />
<result property="name" column="name" />
<result property="password" column="password" />
</resultMap>
<insert id="insert" parameterType="com.example.spring.entity.user">insert into user(name,password) values(#{name},#{password})</insert>
<select id="findName" resultType="com.example.spring.entity.user">SELECT id, name,password
FROM user
WHERE name = #{name}</select>
</mapper>
点击小红鸟,就会帮你在com.example.spring.mapper下创建UserMapper的接口
package com.example.spring.mapper;
import com.example.spring.entity.user;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UserMapper {
int insert(user user);
List<user> findName(String name);
}
然后创建service在项目文件夹下创建UserSerice接口
package com.example.spring.service;
import com.example.spring.entity.user;
import java.util.List;
public interface UserService {
List<user> findName(String name);
int insert(user user);
}
再创建impl文件夹和UserImpl类
package com.example.spring.impl;
import com.example.spring.entity.user;
import com.example.spring.mapper.UserMapper;
import com.example.spring.service.UserSerice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserImpl implements UserSerice {
@Autowired
private UserMapper userMapper;
@Override
public List<user> findName(String name) {
List<user> user = userMapper.findName(name);
return user;
}
@Override
public int insert(user user) {
int i = userMapper.insert(user);
return i;
}
}
我们前后端通信常用json原版json太乱,此处添加依赖到pom.xml
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.35</version>
</dependency>
建controller文件夹和usercontroller类
package com.example.spring.controller;
import cn.hutool.json.JSONObject;
import com.example.spring.entity.user;
import com.example.spring.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/user")
public class usercontroller {
@Autowired
private UserSerice userService;
@RequestMapping("/findName")
@ResponseBody
public String findName(String name,String password){
user u1 = new user();
JSONObject jo = new JSONObject();
List<user> name1 = userService.findName(name);
if(name1.isEmpty()){
jo.put("msg","用户不存在");
jo.put("code",400);
return jo.toString();
}else {
for(user u:name1){
System.out.println(u);
if(u.getPassword().equals(password)){
u1.setId(u.getId());
u1.setName(u.getName());
u1.setPassword(u.getPassword());
jo.put("msg","登录成功");
jo.put("code",200);
jo.put("user",u1);
return jo.toString();
}
else {
jo.put("msg","登录失败");
jo.put("code",400);
return jo.toString();
}
}}
jo.put("msg","登录失败");
jo.put("code",0);
return jo.toString();
}
@RequestMapping("/insert")
@ResponseBody
public String insert(String name,String password){
System.out.println(name + password);
user u1 = new user();
u1.setName(name);
u1.setPassword(password);
System.out.println(u1);
int i = userService.insert(u1);
if (i>0){
JSONObject jo = new JSONObject();
jo.put("code",200);
jo.put("msg","注册成功");
return jo.toString();
}
else {
JSONObject jo = new JSONObject();
jo.put("code",400);
jo.put("msg","注册失败");
return jo.toString();
}
}
}
ok,后端全部完事,现在在前段完成一下js的ajex刷新
代码可直接替换
function login() {
const username = document.getElementById('loginUsername').value;
const password = document.getElementById('loginPwd').value;
console.log(username + password);
if (!username || !password) {
alert('请输入用户名和密码');
return;
}
fetch('/user/findName', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: `name=${username}&password=${password}`
})
.then(response => response.json())
.then(data => {
if (data.code === 200) {
alert('登录成功');
alert(data.user.name);
alert(data.user.id);
} else {
alert('登录失败');
}
})
.catch(error => {
console.error('登录失败:', error);
alert('登录失败');
});
}
function register() {
var username = document.getElementById('registerUsername').value;
var password = document.getElementById('registerPwd').value;
var passwordConfirm = document.getElementById('registerPwdConfirm').value;
if (!username || !password || !passwordConfirm) {
alert('请输入用户名和密码');
return;
}
if (password !== passwordConfirm) {
alert('两次密码不一致');
return;
}
if (password.length <= 6) {
alert('密码不能少于6位');
return;
}
fetch('/user/insert', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: `name=${username}&password=${password}`
})
.then(response => response.json())
.then(data => {
if (data.code === 200) {
alert('注册成功');
} else {
alert('注册失败');
console.log(data);
}
})
.catch(error => {
console.error('注册失败:', error);
alert('注册失败');
});
}
function toggleBox() {
['loginBox', 'regBox'].forEach(id => document.getElementById(id).classList.toggle('hidden'));
}
原理说明:
该软件分前端后端
前端向后端发送post请求,对应index.js的
fetch('/user/findName', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(loginData)
})
后端对应的代码
@RequestMapping("/user")
该代码一般在类名前和方法前
如usercontroller类名前设置/user方法前写/findname
那该接口就是127.0.0.1:8080/user/findname
接下来上专业软件测试一下接口
接下来分析一下前端ajex刷新
fetch('/user/insert', {
method: 'POST',//设定请求方式
headers: {
'Content-Type': 'application/x-www-form-urlencoded'//设定请求格式
},
body: `name=${username}&password=${password}`//请求内容
})
.then(response => response.json())//接受返回信息
.then(data => {//从data中取code判断
if (data.code === 200) {
alert('注册成功');
} else {
alert('注册失败');
console.log(data);
}
})
.catch(error => {
console.error('注册失败:', error);
alert('注册失败');
});
注意该方法是异步的,不要直接在请求结果里读存变量
再来看看后端
先是mapper.xml,写好我们查询的语句
用一个mapper接口用来调用语句
要添加mapper注解,让springboot扫描到这是一个接口
然后写一个服务接口用于规范impl(实现类)
在实现类中加@Service并继承接口
@Autowired添加该注解注入mapper
public int insert(user user) {
int i = userMapper.insert(user);
return i;
}
findname很好理解
但insert为啥int一个i,因为insert返回他修改了多少行只返回int数据如果想确认是否正确就再写一个mapper在impl实现,此处impl就是一个切片
然后在controller也注入service,就可以直接使用该接口的实现类了,返回json让前端解析即可
实现及(从上往下)
mapper文件
数据库访问层
服务层
实体层
业务实现层
控制层
这是springboot最基础的分层关系,后续还有切片(AOP),拦截器,异常处理,自定义注解等