SpringBoot和Vue实现用户登录注册与异常处理——基于SpringBoot和Vue的后台管理系统项目系列博客(十三)

系列文章目录

  1. 系统功能演示——基于SpringBoot和Vue的后台管理系统项目系列博客(一)
  2. Vue2安装并集成ElementUI——基于SpringBoot和Vue的后台管理系统项目系列博客(二)
  3. Vue2前端主体框架搭建——基于SpringBoot和Vue的后台管理系统项目系列博客(三)
  4. SpringBoot后端初始框架搭建——基于SpringBoot和Vue的后台管理系统项目系列博客(四)
  5. SpringBoot集成Mybatis——基于SpringBoot和Vue的后台管理系统项目系列博客(五)
  6. SpringBoot实现增删改查——基于SpringBoot和Vue的后台管理系统项目系列博客(六)
  7. SpringBoot实现分页查询——基于SpringBoot和Vue的后台管理系统项目系列博客(七)
  8. SpringBoot实现集成Mybatis-Plus和SwaggerUI——基于SpringBoot和Vue的后台管理系统项目系列博客(八)
  9. Vue实现增删改查——基于SpringBoot和Vue的后台管理系统项目系列博客(九)
  10. SpringBoot实现代码生成器——基于SpringBoot和Vue的后台管理系统项目系列博客(十)
  11. Vue使用路由——基于SpringBoot和Vue的后台管理系统项目系列博客(十一)
  12. SpringBoot和Vue实现导入导出——基于SpringBoot和Vue的后台管理系统项目系列博客(十二)
  13. SpringBoot和Vue实现用户登录注册与异常处理——基于SpringBoot和Vue的后台管理系统项目系列博客(十三)
  14. SpringBoot和Vue实现用户个人信息展示与保存与集成JWT——基于SpringBoot和Vue的后台管理系统项目系列博客(十四)
  15. SpringBoot和Vue实现文件上传与下载——基于SpringBoot和Vue的后台管理系统项目系列博客(十五)
  16. SpringBoot和Vue整合ECharts——基于SpringBoot和Vue的后台管理系统项目系列博客(十六)
  17. SpringBoot和Vue实现权限菜单功能——基于SpringBoot和Vue的后台管理系统项目系列博客(十七)
  18. SpringBoot实现1对1、1对多、多对多关联查询——基于SpringBoot和Vue的后台管理系统项目系列博客(十八)
  19. 用户前台页面设计与实现——基于SpringBoot和Vue的后台管理系统项目系列博客(十九)
  20. SpringBoot集成Redis实现缓存——基于SpringBoot和Vue的后台管理系统项目系列博客(二十)
  21. SpringBoot和Vue集成高德地图——基于SpringBoot和Vue的后台管理系统项目系列博客(二十一)
  22. SpringBoot和Vue集成视频播放组件——基于SpringBoot和Vue的后台管理系统项目系列博客(二十二)
  23. SpringBoot和Vue集成Markdown和多级评论——基于SpringBoot和Vue的后台管理系统项目系列博客(二十三)

项目资源下载

  1. GitHub下载地址
  2. Gitee下载地址
  3. 项目MySql数据库文件


前言

  今天的主要内容包括:数据传输对象的创建、用户登录后台功能的实现、新建包装类统一返回结果、使用自定义异常处理、使用包装类统一返回结果、用户登录前端功能的实现、用户登录功能测试、用户注册后端功能的实现、用户注册前端功能的实现、用户注册功能测试、用户个人信息展示与保存功能的实现等内容。可以看到今天的内容比较多,废话不多说,下面就开始今天的学习!


一、数据传输对象

  1. 在此目录下新建UserDTO,用于用户登录使用,输入如下内容
    在这里插入图片描述

二、用户登录后台功能的实现

  1. 在UserController.java中新建用户登录的函数,为Post请求
    在这里插入图片描述
  2. 然后在login报红那里按住Alt+Enter,在IUserService.java中生成用户登录接口
    在这里插入图片描述
  3. 然后在UserServiceImpl.java中在报红的那里按住Alt+Enter继承用户登录接口
    在这里插入图片描述
  4. 继承用户登录接口之后如下所示
    在这里插入图片描述
  5. 然后在UserCountroller.java中简单校验
    在这里插入图片描述
  6. 然后在UserServiceImpl中校验是否存在当前用户名和密码
    在这里插入图片描述

三、新建包装类统一返回结果

  1. 在数据库中插入“头像”字段
    在这里插入图片描述
  2. 在User.java中加入“头像”属性
    在这里插入图片描述
  3. 在UserDTO中加入“昵称”和“头像”供登录使用
    在这里插入图片描述
  4. 在此目录下新建Constants.java,要注意这是一个接口
    在这里插入图片描述
  5. 在其中加入如下内容,写一些标志码
    在这里插入图片描述
  6. 在此目录下新建Result.java
    在这里插入图片描述
  7. 在Result.java中加入如下内容,将返回结果封装起来,使代码规范便捷
package com.ironmanjay.springboot.common;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 接口统一返回包装类
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {

    // 返回成功还是失败
    private String code;
    // 失败的原因
    private String msg;
    // 后台所需要携带的数据
    private Object data;

    /**
     * 无数据的成功请求
     *
     * @return 返回封装的结果
     */
    public static Result success() {
        return new Result(Constants.CODE_200, "", null);
    }

    /**
     * 有数据的成功请求
     *
     * @param data 请求得到的数据
     * @return 返回封装的结果
     */
    public static Result success(Object data) {
        return new Result(Constants.CODE_200, "", data);
    }

    /**
     * 请求错误
     *
     * @param code 错误标志码
     * @param msg  错误信息
     * @return 返回封装的结果
     */
    public static Result error(String code, String msg) {
        return new Result(code, msg, null);
    }

    /**
     * 默认的请求错误
     *
     * @return 返回封装的结果
     */
    public static Result error() {
        return new Result(Constants.CODE_500, "系统错误", null);
    }

}

四、使用自定义异常处理

  1. 在此目录下新建ServiceException.java
    在这里插入图片描述
  2. 在其中输入如下内容,用于自定义异常
    在这里插入图片描述
  3. 在此目录下新建GlobalExceptionHandler.java,用于处理异常
    在这里插入图片描述
  4. 在其中输入如下代码
    在这里插入图片描述

五、使用包装类统一返回结果

  1. 首先封装一个函数用来判断当前用户是否存在
    在这里插入图片描述
  2. 修改UserServiceImpl.java中内容如下所示,不仅将返回结果封装了,还使用了自定义异常处理
    在这里插入图片描述
  3. 将IUserService.java中函数的返回内容修改为UserDTO
    在这里插入图片描述
  4. 修改UserController.java中的内容如下所示,使用我们刚才自定义的返回内容
    在这里插入图片描述

六、用户登录前端功能的实现

  1. 在数据库中给测试用户加上头像的链接信息,读者可以放上自己的头像链接,我的头像链接使用的是CSDN的头像链接,但是要注意网上的图片一般都有防盗链,只需要在里面加上referrerPolicy="no-referrer即可,具体代码见Header.vue
    在这里插入图片描述
  2. 然后将Login.vue的全部内容修改为如下所示
<template>
    <div class="wrapper">
        <div style="margin: 200px auto; background-color: #fff; width: 350px; height: 300px; padding: 20px; border-radius: 10px">
            <div style="margin: 20px 0; text-align: center; font-size: 24px"><b>登 录</b></div>
            <el-form :model="user" :rules="rules" ref="userForm">
                <el-form-item prop="username">
                    <el-input size="medium" style="margin: 10px 0" prefix-icon="el-icon-user"
                              v-model="user.username"></el-input>
                </el-form-item>
                <el-form-item prop="password">
                    <el-input size="medium" style="margin: 10px 0" prefix-icon="el-icon-lock" show-password
                              v-model="user.password"></el-input>
                </el-form-item>
                <el-form-item style="margin: 10px 0; text-align: right">
                    <el-button type="primary" size="small" autocomplete="off" @click="login">登录</el-button>
                    <el-button type="warning" size="small" autocomplete="off" @click="$router.push('/register')">注册</el-button>
                </el-form-item>
            </el-form>
        </div>
    </div>
</template>

<script>
    export default {
        name: "Login",
        data() {
            return {
                user: {},
                rules: {
                    username: [
                        {required: true, message: '请输入用户名', trigger: 'blur'},
                        {min: 3, max: 10, message: '长度在 3 到 5 个字符', trigger: 'blur'}
                    ],
                    password: [
                        {required: true, message: '请输入密码', trigger: 'blur'},
                        {min: 1, max: 20, message: '长度在 1 到 20 个字符', trigger: 'blur'}
                    ],
                }
            }
        },
        methods: {
            login() {
                this.$refs['userForm'].validate((valid) => {
                    if (valid) {  // 表单校验合法
                        this.request.post("/user/login", this.user).then(res => {
                            if (res.code == '200') {
                                localStorage.setItem("user",JSON.stringify(res.data)) // 存储用户信息到浏览器
                                this.$router.push("/")
                                this.$message.success("登陆成功")
                            } else {
                                this.$message.error(res.msg)
                            }
                        })
                    }
                });
            }
        }
    }
</script>

<style>
    .wrapper {
        height: 100vh;
        background-image: linear-gradient(to bottom right, #FC466B, #3F5EFB);
        overflow: hidden;
    }
</style>
  1. 然后将Header.vue的全部内容修改为如下所示
<template>
    <div style="line-height: 60px; display: flex">
        <div style="flex: 1;">
            <span :class="collapseBtnClass" style="cursor: pointer; font-size: 18px" @click="collapse"></span>
            <el-breadcrumb separator="/" style="display: inline-block; margin-left: 10px">
                <el-breadcrumb-item :to="'/'">首页</el-breadcrumb-item>
                <el-breadcrumb-item>{{ currentPathName }}</el-breadcrumb-item>
            </el-breadcrumb>
        </div>
        <el-dropdown style="width: 150px; cursor: pointer; text-align: right">
            <div style="display: inline-block">
                <img :src="user.avatar" referrerPolicy="no-referrer"
                     style="width: 30px; border-radius: 50%; position: relative; top: 10px; right: 5px">
                <span>{{ user.nickname }}</span><i class="el-icon-arrow-down" style="margin-left: 5px"></i>
            </div>
            <el-dropdown-menu slot="dropdown" style="width: 100px; text-align: center">
                <el-dropdown-item style="font-size: 14px; padding: 5px 0">
                    <router-link to="/password">修改密码</router-link>
                </el-dropdown-item>
                <el-dropdown-item style="font-size: 14px; padding: 5px 0">
                    <router-link to="/person">
                        个人信息
                    </router-link>
                </el-dropdown-item>
                <el-dropdown-item style="font-size: 14px; padding: 5px 0">
                    <span style="text-decoration: none" @click="logout">退出</span>
                </el-dropdown-item>
            </el-dropdown-menu>
        </el-dropdown>
    </div>
</template>

<script>
    export default {
        name: "Header",
        props: {
            collapseBtnClass: String,
        },
        computed: {
            currentPathName() {
                return this.$store.state.currentPathName;  //需要监听的数据
            }
        },
        data() {
            return {
                user: localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {}
            }
        },
        methods: {
            collapse() {
                this.$emit("asideCollapse")
            },
            logout() {
                this.$router.push("/login")
                localStorage.removeItem("user")
                this.$message.success("退出成功")
            }
        }
    }
</script>

<style scoped>
</style>
  1. 然后在index.js中加入用户登录界面的路由
    在这里插入图片描述

七、用户登录功能测试

  1. 我们使用admin测试账号登录
    在这里插入图片描述
  2. 发现可以登录成功,并且成功获取到当前用户信息
    在这里插入图片描述

八、用户注册后端功能的实现

  1. 在UserServiceImpl.java中加入用户注册的函数
    在这里插入图片描述
  2. 在IUserService.java中写这个接口
    在这里插入图片描述
  3. 在UserController.java中增加用户注册的路由
    在这里插入图片描述

九、用户注册前端功能的实现

  1. 在Vue项目的views中新建Register.vue
    在这里插入图片描述
  2. 在其中输入如下内容
<template>
    <div class="wrapper">
        <div style="margin: 200px auto; background-color: #fff; width: 350px; height: 400px; padding: 20px; border-radius: 10px">
            <div style="margin: 20px 0; text-align: center; font-size: 24px"><b>注 册</b></div>
            <el-form :model="user" :rules="rules" ref="userForm">
                <el-form-item prop="username">
                    <el-input placeholder="请输入账号" size="medium" style="margin: 5px 0" prefix-icon="el-icon-user"
                              v-model="user.username"></el-input>
                </el-form-item>
                <el-form-item prop="password">
                    <el-input placeholder="请输入密码" size="medium" style="margin: 5px 0" prefix-icon="el-icon-lock"
                              show-password
                              v-model="user.password"></el-input>
                </el-form-item>
                <el-form-item prop="confirmPassword">
                    <el-input placeholder="请确认密码" size="medium" style="margin: 5px 0" prefix-icon="el-icon-lock"
                              show-password
                              v-model="user.confirmPassword"></el-input>
                </el-form-item>
                <el-form-item style="margin: 10px 0; text-align: right">
                    <el-button type="primary" size="small" autocomplete="off" @click="login">注册</el-button>
                    <el-button type="warning" size="small" autocomplete="off" @click="$router.push('/login')">返回登陆</el-button>
                </el-form-item>
            </el-form>
        </div>
    </div>
</template>

<script>
    export default {
        name: "Login",
        data() {
            return {
                user: {},
                rules: {
                    username: [
                        {required: true, message: '请输入用户名', trigger: 'blur'},
                        {min: 3, max: 10, message: '长度在 3 到 5 个字符', trigger: 'blur'}
                    ],
                    password: [
                        {required: true, message: '请输入密码', trigger: 'blur'},
                        {min: 1, max: 20, message: '长度在 1 到 20 个字符', trigger: 'blur'}
                    ],
                    confirmPassword: [
                        {required: true, message: '请输入确认密码', trigger: 'blur'},
                        {min: 1, max: 20, message: '长度在 1 到 20 个字符', trigger: 'blur'}
                    ],
                }
            }
        },
        methods: {
            login() {
                this.$refs['userForm'].validate((valid) => {
                    if (valid) {  // 表单校验合法
                        if (this.user.password !== this.user.confirmPassword) {
                            this.$message.error("两次输入的密码不一致")
                            return false
                        }
                        this.request.post("/user/register", this.user).then(res => {
                            if (res.code == '200') {
                                this.$message.success("注册成功")
                            } else {
                                this.$message.error(res.msg)
                            }
                        })
                    }
                });
            }
        }
    }
</script>

<style>
    .wrapper {
        height: 100vh;
        background-image: linear-gradient(to bottom right, #FC466B, #3F5EFB);
        overflow: hidden;
    }
</style>
  1. 然后在index.js中加入用户注册界面的路由
    在这里插入图片描述

十、用户注册功能测试

  1. 我们在用户注册界面输入新的用户用于注册,显示注册成功
    在这里插入图片描述
  2. 然后查看数据库发现已经将新注册的用户插入到数据库中
    在这里插入图片描述
  3. 再使用刚才注册的新用户登录,发现可以成功登录
    在这里插入图片描述

十一、用户个人信息展示与保存功能的实现

  1. 首先在UserController.java中加入用户个人信息接口,用于查询用户个人信息
    在这里插入图片描述
  2. 然后在Vue项目的views文件夹中新建Person.vue
    在这里插入图片描述
  3. 在其中输入如下内容
<template>
    <el-card style="width: 500px;">
        <el-form label-width="80px" size="small">
            <el-form-item label="用户名">
                <el-input v-model="form.username" disabled autocomplete="off"></el-input>
            </el-form-item>
            <el-form-item label="昵称">
                <el-input v-model="form.nickname" autocomplete="off"></el-input>
            </el-form-item>
            <el-form-item label="邮箱">
                <el-input v-model="form.email" autocomplete="off"></el-input>
            </el-form-item>
            <el-form-item label="电话">
                <el-input v-model="form.phone" autocomplete="off"></el-input>
            </el-form-item>
            <el-form-item label="地址">
                <el-input v-model="form.address" autocomplete="off"></el-input>
            </el-form-item>
            <el-form-item>
                <el-button type="primary" @click="save">保 存</el-button>
            </el-form-item>
        </el-form>
    </el-card>
</template>

<script>
    export default {
        name: "Person",
        data() {
            return {
                form: {},
                user: localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {}
            }
        },
        created() {
            this.request.get("/user/username/" + this.user.username).then(res => {
                if (res.code == '200') {
                    this.form = res.data
                }
            })
        },
        methods: {
            save() {
                this.request.post("/user", this.form).then(res => {
                    if (res) {
                        this.$message.success("保存成功")
                    } else {
                        this.$message.error("保存失败")
                    }
                })
            }
        }
    }
</script>

<style scoped>

</style>
  1. 最后在index.js中加入用户信息界面的路由,注意是作为Manage.vue的子路由
    在这里插入图片描述
  2. 最后测试一下,发现可以成功获取到当前用户的个人信息
    在这里插入图片描述

总结

  到此为止我们今天的学习就告一段落了,可以看到内容非常多,也有一定的难度,但是跟着我一步一步做下来肯定没问题。今天就先到这里,明天将给大家带来关于SpringBoot和Vue实现用户个人信息展示与保存与集成JWT的内容。明天见!

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IronmanJay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值