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;
    }
}

会员注册时需要对密码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;
    }
}

接下来开始写注册业务逻辑,在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);
}

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;
    }
}

在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", "测试");
    }
}

Java项目(三)-- SSM开发社交网站(7)--会员注册与登录_第1张图片
测试成功
Java项目(三)-- SSM开发社交网站(7)--会员注册与登录_第2张图片
再次运行测试用例会报用户名存在异常,符合我们业务逻辑。
Java项目(三)-- SSM开发社交网站(7)--会员注册与登录_第3张图片
然后打开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;
    }

运行项目,在浏览器中访问http://localhost:8080/register.html测试注册功能。
Java项目(三)-- SSM开发社交网站(7)--会员注册与登录_第4张图片
Java项目(三)-- SSM开发社交网站(7)--会员注册与登录_第5张图片

实现会员登录功能

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

    /**
     * 登录检查
     * @param username 用户名
     * @param password 密码
     * @return
     */
    public Member checkLogin(String username, String password);

然后,在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;
    }

然后打开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;
}

前端代码为:在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>

运行项目测试
Java项目(三)-- SSM开发社交网站(7)--会员注册与登录_第6张图片
Java项目(三)-- SSM开发社交网站(7)--会员注册与登录_第7张图片

你可能感兴趣的:(Java项目,java,junit,单元测试)