SpringBoot+MyBatis+MySql从头到尾完成一个电商项目(五、用户注册、登录)

本文介绍了如何使用SpringBoot、MyBatis和MySQL完成一个电商项目的用户注册和登录功能。从获取短信验证码的接口编写,到前后端分离的注册界面实现,再到用户注册接口开发,最后实现用户登录功能,全程详细讲解每个步骤,并解决了密码表与用户信息表关联的问题。

1、码云新建一个分支user-register

2、用户获取短信验证码otp的接口编写:

首先在UserController中注入HttpServletRequest这样我们可以拿到Session

然后写接口如下:

然后启动程序进行测试结果如下:

再看一下我们的控制台打印出来了电话和验证码,这里只是测试,正规的企业开发不能暴漏用户的验证码!!

3、下面我们通过前后端分离的方式把前端的注册界面做出来:

这里我们整合前后端使用的是thymeleaf,先去application,properties中添加如下设置:

然后开始前端页面的书写:

在static包下新建一个getotp.html的网页如下图:

这里是界面的编写,可以看一下效果如下:

然后下面是js代码的书写,这里我们使用jquery采用ajax进行前后端的传值!

<script>
    // 所有的jquery的动态绑定元素需要页面渲染完成以后才可以操作
    jQuery(document).ready(function () {

        //绑定otp的点击事件,用于向后端发送获取验证码的实现
        $("#getotp").on("click",function () {

            var telphone=$("#telphone").val();
            if(telphone==null || telphone==""){
                alert("手机号不能为空");
                //我们使用的是ajax传值,所以要捕获点击事件,不让它冒泡排序到上一层
                return false;
            }
            $.ajax({
                //头
                type:"POST",
                contentType:"application/x-www-form-urlencoded",
                url:"http://localhost:8090/user/getotp",

                //传参
                data:{
                    //获取用户输入的telphone
                    "telphone":$("#telphone").val(),
                },
                //成功的回调函数
                //data是后端输出的json数据
                //与后端的@CrossOrigin(allowCredentials = "true",allowedHeaders = "*")相互呼应
                xhrFields:{withCredentials:true},
                success:function (data) {
                    if(data.status==="success"){
                        alert("otp已经发送到你的手机上,请注意查收");
                        window.location.href="file:///H:/fondend/miaosha/src/main/resources/static/register.html";
                    }else {
                        alert("otp发送失败,原因为"+data.data.errMsg);
                    }

                },
                //失败的回调函数
                error:function (data) {
                    alert("otp发送失败,原因为"+data.responseText);
                }
            });
            return false;
        });

    });

</script>

在这里跟大家解释一下逻辑顺序:

首先当用户输入手机号然后点击确定后会出发jquery的点击事件的方法,然后可以使用$("#telphone").val()获取用户输入的手机号进行判断手机号是否为空。如果手机号不为空,使用ajax进行前后端的传值,ajax传值包括4个部分,一个是 头 部分如下图:

这里type是指传值的方式,包括GET  PUT  POST等形式,

contentType是传值的格式,

url是指传值的接口,这里写的是我们在上面写好的获取otp的接口,注意在url里面不要写参数,只写url。

一个是传参部分,这里前端传给后端的值是用户输入的手机号,用来于接口url进行组合获取信息;如下图:

第三个部分是前后端传值成功的函数:

这里如果传值成功,会将页面跳转至用户注册界面进行注册。

第四部分是传值失败的回调函数如下图:

这里会将失败的原因用弹框的形式展示。

这里我们在static下新建一个register.html页面,然后进行getotp页面的调试。

启动程序进行调试如下:

这里我们暂时还是在控制台打印验证码,去控制台看一下:

已经打印出了验证码,说明我们前后端的传值已经成功!

4、下面我们正式开始用户注册的开发,首先开发用户注册的接口:

//用户注册接口
@RequestMapping(value = "/register",method = {RequestMethod.POST},consumes={CONTENT_TYPE_FORMED})
@ResponseBody
//需要参数:手机号,验证码,用户名,性别,年龄
public CommonReturnType register(@RequestParam(name = "telphone") String telphone,
                                 @RequestParam(name = "otpCode") String otpCode,
                                 @RequestParam(name = "name") String name,
                                 @RequestParam(name = "gender") Integer gender,
                                 @RequestParam(name = "age") Integer age,
                                 @RequestParam(name = "password") String password
                                 ) throws BusinessException, UnsupportedEncodingException, NoSuchAlgorithmException {
    //验证手机号和对应的otpCode相符
    String inSessionOtpCode= (String) this.httpServletRequest.getSession().getAttribute(telphone);
    //使用阿里巴巴的等值判别,好处是已经做了非空判断
    if (!StringUtils.equals(otpCode,inSessionOtpCode)){
        throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR,"短信验证码不符合要求!");
    }
    //若手机号与验证码相对应,则开始注册,需要一个service去执行注册流程
    UserModel userModel=new UserModel();
    userModel.setName(name);
    //转换gender的字符串类型
    userModel.setGender(new Byte(String.valueOf(gender.intValue())));
    userModel.setAge(age);
    userModel.setTelphone(telphone);
    userModel.setRegisterMode("byphone");
    //对密码做加密处理

    userModel.setEncrptPassword(this.EncodeByMd5(password));

    userService.register(userModel);
    return CommonReturnType.creat(null);

}

我们来看一些这段代码:首先我们从过传参的形式将前端用户的注册信息传给后端,参数包括用户注册的一些必要参数。

然后验证手机号和对应的otpCode相符。这里使用阿里巴巴的等值判别,好处是已经做了非空判断。

若手机号和验证码相符,则开始注册,这里专门使用一个service进行注册,service如下图:

这里使用一个usermodel进行用户的注册,userModel的内容通过用户传入的参数获得。

然后在serviecImpl中去实现具体的逻辑:

我们仔细来看一下这段代码:首先我们进行判空的处理,这里我们自定义了一个ValidationResult来进行userModel的判空处理,下面我们来看一下ValidationResult这个类:

还要写一个实现校验方法并返回结果的类如下:

这样我们就可以对userModel进行非空校验了,我们着重来看一下校验完成以后的操作。

我们通过register方法可以从前端获取到用户的UserModel信息,现在我们要把用户信息插入到数据库,但是与数据库的交互格式是DataObject,所以这里要实现Model---》DataObject的转换。具体实现方法如下:

然后我们往数据库插入数据,这里使用的是insertSelective方法进行插入,因为这个可以在插入之前判断参数的空值情况。

然后还有密码的插入,这里通过关联用户表来获取用户密码:

由于我们这里只是往数据库插入数据,不需要返回数据,所以最后返回值为null就OK了。

5、下面我们来编写用户注册的前端界面,这里还是采用前后端分离的方式开发,前后端的额数据交互采用ajax。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/jquery.js" type="text/javascript"></script>
    <link href="css/login.css" rel="stylesheet">
</head>
<body>
<div id="content">
    <div class="login-header">
        <label>用户注册</label>
    </div>
    <div>
        <label>手机号</label>
        <div>
            <input type="text" placeholder="手机号" name="telphone" id="telphone">
        </div>
    </div>
    <div>
        <label>验证码</label>
        <div>
            <input type="text" placeholder="验证码" name="otpCode" id="otpCode">
        </div>
    </div>
    <div>
        <label>用户昵称</label>
        <div>
            <input type="text" placeholder="用户昵称" name="name" id="name">
        </div>
    </div>
    <div>
        <label>性别</label>
        <div>
            <input type="text" placeholder="性别" name="gender" id="gender">
        </div>
    </div>
    <div>
        <label>年龄</label>
        <div>
            <input type="text" placeholder="年龄" name="age" id="age">
        </div>
    </div>
    <div>
        <label>密码</label>
        <div>
            <input type="password" placeholder="密码" name="password" id="password">
        </div>
    </div>
    <div>
        <button id="register" type="submit">
            提交注册
        </button>
    </div>
</div>
</body>

<script>
    // 所有的jquery的动态绑定元素需要页面渲染完成以后才可以操作
    jQuery(document).ready(function () {

        //绑定otp的点击事件,用于向后端发送获取验证码的实现
        $("#register").on("click",function () {
            //拿到界面上所有元素的值
            var telphone=$("#telphone").val();
            var otpCode=$("#otpCode").val();
            var name=$("#name").val();
            var gender=$("#gender").val();
            var age=$("#age").val();
            var password=$("#password").val();

            if(telphone==null || telphone==""){
                alert("手机号不能为空");
                //我们使用的是ajax传值,所以要捕获点击事件,不让它冒泡排序到上一层
                return false;
            }
            if(password==null || password==""){
                alert("密码不能为空");
                //我们使用的是ajax传值,所以要捕获点击事件,不让它冒泡排序到上一层
                return false;
            }
            if(age==null || age==""){
                alert("年龄不能为空");
                //我们使用的是ajax传值,所以要捕获点击事件,不让它冒泡排序到上一层
                return false;
            }
            if(gender==null || gender==""){
                alert("性别不能为空");
                //我们使用的是ajax传值,所以要捕获点击事件,不让它冒泡排序到上一层
                return false;
            }
            if(name==null || name==""){
                alert("姓名不能为空");
                //我们使用的是ajax传值,所以要捕获点击事件,不让它冒泡排序到上一层
                return false;
            }
            if(telphone==null || telphone==""){
                alert("手机号不能为空");
                //我们使用的是ajax传值,所以要捕获点击事件,不让它冒泡排序到上一层
                return false;
            }
            if(otpCode==null || otpCode==""){
                alert("验证码不能为空");
                //我们使用的是ajax传值,所以要捕获点击事件,不让它冒泡排序到上一层
                return false;
            }
            $.ajax({
                //头
                type:"POST",
                contentType:"application/x-www-form-urlencoded",
                url:"http://localhost:8088/user/register",

                //传参
                data:{
                    //获取用户输入的telphone\password等值
                    "telphone":telphone,
                    "otpCode":otpCode,
                    "name":name,
                    "gender":gender,
                    "age":age,
                    "password":password,
                },
                //成功的回调函数
                //data是后端输出的json数据
                //与后端的@CrossOrigin(allowCredentials = "true",allowedHeaders = "*")相互呼应
                xhrFields:{withCredentials:true},
                success:function (data) {
                    if(data.status==="success"){
                        alert("注册成功");
                    }else {
                        alert("注册失败,原因为"+data.data.errMsg);
                    }

                },
                //失败的回调函数
                error:function (data) {
                    alert("注册失败,原因为"+data.responseText);
                }
            });
            return false;
        });

    });

</script>
</html>

然后进行调试,把程序启动然后进行测试!

我们可以看到注册成功,下面去数据库看一下数据是否插入:

用户信息已经插入,然后来看一下密码表的信息:

我们可以看到密码表在跟用户信息表关联时出了一点问题,即密码没有跟用户id关联上。这是什么原因呢,我们排查一下代码!

其实问题出现在我们在具体执行注册时的这个方法中,我们需要在UserDOMapper里面加上这一句:

 

通过这种方式将自增id取出来并赋值给userModel,以便于转发给对应的userPassword。现在我们再次测试就会成功了!!这里不再赘述。

6、我们进行用户登录功能的开发,首先还是先开发接口:

我们来解读一下代码,首先在controller层中传入通过前端获得的用户输入的手机号和密码,然后进行非空等校验,校验完成以后我们通过service进行用户登录是否合法的验证如下:

然后再通过具体的serviceImpl方法去实现它:

我们再来解释一下这段代码:

首先我们要重新写一个sql,通过用户手机号来获取用户密码信息:

这样我们使用sql写了一个方法通过用户手机号去获取用户信息,然后记得在UserDOMapper中添加这个方法如下图:

这样就可以在UserServiceImpl中使用这个方法通过用户手机号去获取用户信息了。

然后进行判空处理,记住我们只要是设计到具体的对象都要进行判空处理,这样会使我们的程序非常健壮!

这里我们需要去EmBusinessError里面再定义一个错误类型如下:

然后我们这里拿到的都是DO对象,需要转换成model对象返回,如下图:

我们将用户登录成功后的model对象放到session里面如下图:

最后返回给前端一个用户正确登录的信息。

7、最后我们写一下登录的前端界面:

<!DOCTYPE html>
<html lang="en"
      xmlns:th=“http://www.thymeleaf.org”>

<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
    <script src="js/jquery.js" type="text/javascript"></script>
    <link href="css/login.css" rel="stylesheet"/>
</head>
<body>
<div id="content">
    <div class="login-header">
        <img src="assets/login_header.png">
    </div>
    <form>
        <div class="login-input-box">
            <span class="icon icon-user"></span>
            <input type="text" placeholder="手机号" name="telphone" id="telphone">
        </div>

        <div class="login-input-box">
            <span class="icon icon-password"></span>
            <input type="password" placeholder="密码" name="password" id="password">
        </div>
    </form>

    <div>
        <button id="login" type="submit" class="login-button-box">
            登录
        </button>
        <button id="register" type="submit" class="logon-box">
            注册
        </button>
    </div>
</div>
</body>

<script>
    // 所有的jquery的动态绑定元素需要页面渲染完成以后才可以操作
    jQuery(document).ready(function () {
        //绑定注册按钮的点击事件
        $("#register").on("click",function (){
            window.location.href="getotp.html";
        });


        //绑定otp的点击事件,用于向后端发送获取验证码的实现
        $("#login").on("click",function () {
            //拿到界面上所有元素的值
            var telphone=$("#telphone").val();
            var password=$("#password").val();


            if(telphone==null || telphone==""){
                alert("手机号不能为空");
                //我们使用的是ajax传值,所以要捕获点击事件,不让它冒泡排序到上一层
                return false;
            }
            if(password==null || password==""){
                alert("密码不能为空");
                //我们使用的是ajax传值,所以要捕获点击事件,不让它冒泡排序到上一层
                return false;
            }

            $.ajax({
                //头
                type:"POST",
                contentType:"application/x-www-form-urlencoded",
                url:"http://localhost:8088/user/login",

                //传参
                data:{
                    //获取用户输入的telphone\password等值
                    "telphone":telphone,
                    "password":password,
                },
                //成功的回调函数
                //data是后端输出的json数据
                //与后端的@CrossOrigin(allowCredentials = "true",allowedHeaders = "*")相互呼应
                xhrFields:{withCredentials:true},
                success:function (data) {

                    console.log(data);
                    if(data.status==="success"){
                        alert("登录成功");
                        window.location.href="listproduct.html"
                    }else {
                        alert("登录失败,原因为"+data.data.errMsg);
                    }

                },
                //失败的回调函数
                error:function (data) {
                    alert("登录失败,原因为"+data.responseText);
                }
            });
            return false;
        });

    });

</script>
</html>

经测试没有问题!!至此,用户的注册和登录功能已经完成,下一步要进行商品相关功能的开发,加油!!

最后记得提交代码:

git add .

git commit -m 'user_develop'

git push

也可以把分支合并到主分支,并且提交主分支代码!

git checkout master

git merge origin/user_develop

git push

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值