使用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

接下来上专业软件测试一下接口

屏幕截图 2025-09-01 114106.png

接下来分析一下前端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),拦截器,异常处理,自定义注解等

代码附上:蓝奏云 提取码XZBy


使用Springboots完成一个登陆网站
https://fengliangit.cn:9999/archives/springboot-login
作者
fengliang
发布于
2025年09月01日
许可协议