• Java项目(三)-- SSM开发社交网站(7)--会员注册与登录


    实现会员注册功能

    首先,为了业务方法返回错误信息格式的统一,我们在com.ql.reader.service.exception包下创建一个自定义异常:

    package com.ql.reader.service.exception;
    
    /**
     * BussinessException业务逻辑异常
     */
    public class BussinessException extends RuntimeException{
        private String code;
        private String msg;
        public BussinessException(String code, String msg){
            super(msg);
            this.code = code;
            this.msg = msg;
        }
    
        public String getCode() {
            return code;
        }
    
        public void setCode(String code) {
            this.code = code;
        }
    
        public String getMsg() {
            return msg;
        }
    
        public void setMsg(String msg) {
            this.msg = msg;
        }
    }
    
    
    • 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

    会员注册时需要对密码MD5加密存储,所以在com.ql.reader.utils包下创建MD5工具类

    package com.ql.reader.utils;
    
    import org.apache.commons.codec.digest.DigestUtils;
    
    public class MD5Utils {
        public static String md5Digest(String source, Integer salt){
            char[] ca = source.toCharArray();
            //混淆源数据
            for (int i = 0; i < ca.length; i++) {
                ca[i] = (char) (ca[i] + salt);
            }
            String target = new String(ca);
            String md5 = DigestUtils.md5Hex(target);
            return md5;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    接下来开始写注册业务逻辑,在com.ql.reader.service包下创建会员业务接口,并且在com.ql.reader.service.impl包下创建它的实现类

    package com.ql.reader.service;
    
    import com.ql.reader.entity.Member;
    
    public interface MemberService {
        /**
         * 会员注册,创建新会员
         * @param username 用户名
         * @param password 密码
         * @param nickname 昵称
         * @return 新会员对象
         */
        public Member createMember(String username, String password, String nickname);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    package com.ql.reader.service.impl;
    
    import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    import com.ql.reader.entity.Member;
    import com.ql.reader.mapper.MemberMapper;
    import com.ql.reader.service.MemberService;
    import com.ql.reader.service.exception.BussinessException;
    import com.ql.reader.utils.MD5Utils;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    import javax.annotation.Resource;
    import java.util.Date;
    import java.util.List;
    import java.util.Random;
    
    @Service("memberService")
    @Transactional
    public class MemberServiceImpl implements MemberService {
        @Resource
        private MemberMapper memberMapper;
        /**
         * 会员注册,创建新会员
         *
         * @param username 用户名
         * @param password 密码
         * @param nickname 昵称
         * @return 新会员对象
         */
        public Member createMember(String username, String password, String nickname) {
            QueryWrapper<Member> queryWrapper = new QueryWrapper<Member>();
            queryWrapper.eq("username", username);
            List<Member> memberList = memberMapper.selectList(queryWrapper);
            //判断用户名是否已存在
            if(memberList.size()>0){
                throw new BussinessException("M01", "用户名已存在");
            }
            Member member = new Member();
            member.setUsername(username);
            member.setNickname(nickname);
            int salt = new Random().nextInt(1000) + 1000;//盐值
            String md5 = MD5Utils.md5Digest(password, salt);
            member.setPassword(md5);
            member.setSalt(salt);
            member.setCreateTime(new Date());
            memberMapper.insert(member);
            return member;
        }
    }
    
    
    • 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

    在src/test/java/com/ql/reader/service/impl目录下生成测试用例,运行测试

    package com.ql.reader.service.impl;
    
    import com.ql.reader.service.MemberService;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import javax.annotation.Resource;
    
    import static org.junit.Assert.*;
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = {"classpath:applicationContext.xml"})
    public class MemberServiceImplTest {
        @Resource
        private MemberService memberService;
    
        @Test
        public void createMember() {
            memberService.createMember("s123456", "123456", "测试");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这里插入图片描述
    测试成功
    在这里插入图片描述
    再次运行测试用例会报用户名存在异常,符合我们业务逻辑。
    在这里插入图片描述
    然后打开MemberController.java修改会员注册方法

        @PostMapping("/registe")
        @ResponseBody
        public Map registe(String vc, String username, String password, String nickname, HttpServletRequest request){
            //正确验证码
            String verifyCode = (String) request.getSession().getAttribute("kaptchaVerifyCode");
            //验证码对比
            Map result = new HashMap();
            if (vc==null || verifyCode==null || !vc.equalsIgnoreCase(verifyCode)){
                result.put("code", "VC01");
                result.put("msg", "验证码错误");
            }else{
                try {
                    memberService.createMember(username, password, nickname);
                    result.put("code", "0");
                    result.put("msg", "success");
                } catch (BussinessException e) {
                    e.printStackTrace();
                    result.put("code", e.getCode());
                    result.put("msg", e.getMsg());
                }
            }
            return result;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    运行项目,在浏览器中访问http://localhost:8080/register.html测试注册功能。
    在这里插入图片描述
    在这里插入图片描述

    实现会员登录功能

    首先,打开MemberService.java接口添加登录检查方法

        /**
         * 登录检查
         * @param username 用户名
         * @param password 密码
         * @return
         */
        public Member checkLogin(String username, String password);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    然后,在MemberServiceImpl.java中添加方法实现

        /**
         * 登录检查
         *
         * @param username 用户名
         * @param password 密码
         * @return
         */
        public Member checkLogin(String username, String password) {
            QueryWrapper<Member> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("username", username);
            Member member = memberMapper.selectOne(queryWrapper);
            if(member==null){
                throw new BussinessException("M02", "用户名不存在");
            }
            String md5 = MD5Utils.md5Digest(password, member.getSalt());
            if(!md5.equals(member.getPassword())){
                throw new BussinessException("M03", "输入密码有误");
            }
            return member;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    然后打开MemberController.java添加跳转到登录页和登录验证的方法

    @GetMapping("/login.html")
    public ModelAndView showLogin(){
        return new ModelAndView("/login");
    }
    
    @PostMapping("/check_login")
    @ResponseBody
    public Map checkLogin(String vc, String username, String password, HttpSession session){
        //正确验证码
        String verifyCode = (String)session.getAttribute("kaptchaVerifyCode");
        //验证码对比
        Map result = new HashMap();
        if (vc==null || verifyCode==null || !vc.equalsIgnoreCase(verifyCode)){
            result.put("code", "VC01");
            result.put("msg", "验证码错误");
        }else{
            try {
                Member member = memberService.checkLogin(username, password);
                session.setAttribute("loginMember", member);
                result.put("code", "0");
                result.put("msg", "success");
            } catch (BussinessException e) {
                e.printStackTrace();
                result.put("code", e.getCode());
                result.put("msg", e.getMsg());
            }
        }
        return result;
    }
    
    • 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

    前端代码为:在src/main/webapp/WEB-INF/ftl目录下创建登录页login.ftl

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>会员登录-书评网title>
        <meta name="viewport" content="width=device-width,initial-scale=1.0, maximum-scale=1.0,user-scalable=no">
        <link rel="stylesheet" href="http://cdn.itlaoqi.com./resources/bootstrap4/css/bootstrap.css">
        <link rel="stylesheet" href="./resources/raty/lib/jquery.raty.css">
    
        <script src="http://cdn.itlaoqi.com./resources/jquery.3.3.1.min.js">script>
        <script src="http://cdn.itlaoqi.com./resources/bootstrap4/js/bootstrap.min.js">script>
        <style>
            .container {
                padding: 0px;
                margin: 0px;
            }
    
            .row {
                padding: 0px;
                margin: 0px;
            }
    
            .col- * {
                padding: 0px;
            }
    
            .description p {
                text-indent: 2em;
            }
    
            .description img {
                width: 100%;
            }
    
        style>
    
    head>
    <body>
    
    <div class="container ">
        <nav class="navbar navbar-light bg-white shadow">
            <ul class="nav">
                <li class="nav-item">
                    <a href="/" style="color: #aaa;font-weight: bold">
                        书评网
                    a>
                li>
            ul>
        nav>
    
    
        <div class="container mt-2 p-2 m-0">
            <form id="frmLogin">
                <div class="passport bg-white">
                    <h4 class="float-left">会员登录h4>
                    <h6 class="float-right pt-2"><a href="/register.html">会员注册a>h6>
                    <div class="clearfix">div>
                    <div class="alert d-none mt-2" id="tips" role="alert">
    
                    div>
    
                    <div class="input-group  mt-2 ">
                        <input type="text" id="username" name="username" class="form-control p-4" placeholder="请输入用户名"
                               aria-label="Username" aria-describedby="basic-addon1">
                    div>
    
                    <div class="input-group  mt-4 ">
                        <input id="password" name="password" class="form-control p-4" placeholder="请输入密码" type="password"
                               aria-describedby="basic-addon1">
                    div>
    
                    <div class="input-group mt-4 ">
                        <div class="col-5 p-0">
                            <input type="text" id="verifyCode" name="vc" class="form-control p-4" placeholder="验证码">
                        div>
                        <div class="col-4 p-0 pl-2 pt-0">
                            <img id="imgVerifyCode" src="/verify_code"
                                 style="width: 120px;height:50px;cursor: pointer">
                        div>
    
                    div>
    
                    <a id="btnSubmit" class="btn btn-success  btn-block mt-4 text-white pt-3 pb-3">    a>
                div>
            form>
    
        div>
    div>
    
    <script>
        function showTips(isShow, css, text) {
            if (isShow) {
                $("#tips").removeClass("d-none")
                $("#tips").hide();
                $("#tips").addClass(css);
                $("#tips").text(text);
                $("#tips").fadeIn(200);
            } else {
                $("#tips").text("");
                $("#tips").fadeOut(200);
                $("#tips").removeClass();
                $("#tips").addClass("alert")
            }
        }
        function reloadVerifyCode(){
            $("#imgVerifyCode").attr("src", "/verify_code?ts=" + new Date().getTime());
        }
        $("#imgVerifyCode").click(function () {
            reloadVerifyCode();
        });
    
        $("#btnSubmit").click(function () {
            var username = $.trim($("#username").val());
            var regex = /^.{1,10}$/;
            if (!regex.test(username)) {
                showTips(true, "alert-danger", "用户名请输入正确格式(1-10位)");
                return;
            } else {
                showTips(false);
            }
    
            var password = $.trim($("#password").val());
    
            if (!regex.test(password)) {
                showTips(true, "alert-danger", "密码请输入正确格式(1-10位)");
                return;
            } else {
                showTips(false);
            }
    
            $btnReg = $(this);
    
            $btnReg.text("正在处理...");
            $btnReg.attr("disabled", "disabled");
            $.ajax({
                url: "/check_login",
                type: "post",
                dataType: "json",
                data: $("#frmLogin").serialize(),
                success: function (data) {
                    console.info(data);
                    if (data.code == "0") {
                        window.location = "/?ts=" + new Date().getTime();
                    } else {
                        showTips(true, "alert-danger", data.msg);
                        reloadVerifyCode();
                        $btnReg.text("登录");
                        $btnReg.removeAttr("disabled");
                    }
                }
            });
            return false;
        });
    
    
    script>
    body>
    html>
    
    • 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
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158

    运行项目测试
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    STC单片机+EC11编码器实现调节PWM输出占空比
    Gradle知识概括
    Android 运营商与APN配置简介
    golang: sarama 链接Kafka
    PHP使用 FormBuilder 创建表单
    JSP页面文本展示正常 但定义在java代码中的内容 输出在页面上会变成问号 问题解决
    原创 | 一文读懂 BERT 源代码
    第十二周学习总结 Progress & Lack
    Discuz!X 3.4任意文件删除漏洞
    项目经理在项目中起到的作用
  • 原文地址:https://blog.csdn.net/qq_32091929/article/details/127500669