码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    四、使用自定义异常处理

    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    1. 最后在index.js中加入用户信息界面的路由,注意是作为Manage.vue的子路由
      在这里插入图片描述
    2. 最后测试一下,发现可以成功获取到当前用户的个人信息
      在这里插入图片描述

    总结

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

  • 相关阅读:
    Linux系统之file命令的基本使用
    Codeforces暑期训练周报(8.22~8.28)
    使用dojo.declare进行组件化开发
    LeetCode75——Day14
    【JavaSearch/搜索引擎】项目测试
    【Oracle数据库系列笔记】单行函数
    最短路径问题
    c#中上传超过30mb的文件,接口一直报404,小于30mb的却可以上传成功
    oracle SQL
    6.13 - 特殊含义的IP地址
  • 原文地址:https://blog.csdn.net/IronmanJay/article/details/127700209
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号