【SpringBoot】JavaWeb博客系统——用户登录与注册

项目简介与环境搭建【SpringBoot】JavaWeb博客系统

介绍

界面采用了Semantic ui框,用thymeleaf模板引擎进行渲染。

用户注册时,所要填写的内容主要有用户名,昵称,密码、邮箱,以及验证码。如下图所示。填写完整后,按照实现制定的规则对表单进行校验,如果交过通过,则向后端发送注册信息。完成注册工作。

在这里插入图片描述

代码如下,这里就只展示注册信息填写部分的代码了。完整代码到 github。上看。

<div class="ui five column centered stackable grid">
    <div class="ui  column m-margin-top-large " style="min-width: 480px">
        <div class="ui container m-margin">
            <h2 class="ui center aligned header m-text m-teal">用户注册</h2>
        </div>
        <div class="ui container m-shadow-small">

            <form class="ui form" method="post" action="#">
                <div class="ui  segment">
                    <div class="field">
                        <div class="ui left icon input">
                            <i class="user icon"></i>
                            <input type="text" name="username" class="tooltip" placeholder="用户名"
                                   data-content="由6-16个字母或数字组成,必须以字母开头">
                        </div>
                    </div>
                    <div class="field">
                        <div class="ui left icon input">
                            <i class="tag icon"></i>
                            <input type="text" name="nickname" class="tooltip" placeholder="昵称" data-content="不能为空">
                        </div>
                    </div>
                    <div class="field">
                        <div class="ui left icon input">
                            <i class="lock icon"></i>
                            <input type="password" name="password" class="tooltip" placeholder="密码"
                                   data-content="长度必须为8-16个字符">
                        </div>
                    </div>
                    <div class="field">
                        <div class="ui left icon input">
                            <i class="lock icon"></i>
                            <input type="password" name="repeatpassword" class="tooltip" placeholder="确认密码">
                        </div>
                    </div>
                    <div class="field">
                        <div class="ui left icon input">
                            <i class="envelope icon"></i>
                            <input type="email" name="email" class="tooltip" placeholder="邮箱">
                        </div>
                    </div>
                    <div class="field container">

                        <div class="ui two column grid">
                            <div class="ui column">
                                <div class="ui left icon input">
                                    <i class="check icon"></i>
                                    <input type="text" name="checkcode" class="tooltip" placeholder="验证码"
                                           data-content="请填写验证码">
                                </div>
                            </div>
                            <div class="ui column">
                                <a href="javascript:void(0)" id="checkCode"><img src="static/img/checkcode.png"
                                                                                 th:src="@{/user/checkCode}"
                                                                                 class="rounded checkcode tooltip"
                                                                                 data-content="点击刷新验证码" alt=""></a>
                            </div>
                        </div>
                    </div>
                    <button id="register-btn" class="ui fluid large teal button" type="button">注 册</button>
                </div>

            </form>
        </div>


        <div class="ui container m-margin-top-small">
            <div class="ui bottom attached warning message container center aligned">
                <i class="icon help"></i>
                已经有账号了? <a href="#" th:href="@{/login}">这里登录</a></div>
        </div>

    </div>
</div>

表单校验

Semantic UI提供了表单校验的API,可以通过调用.form()方法,传入指定参数来完成表单校验。用法如下。

先用选择器获取表单对象,调用.form()方法。如果要将提示信息几种到一起显示的话,需要在表单中添加一个带有.error.message的元素,例如

<form class="ui form">
    。。。。。。。。。
    <div class"ui error message"> 
	</div>
</form>

inline表示显示错误提示的方式,默认是false,将会显示在同一行。

fields的值对应了要进行校验的对象,具体解释看代码中的注释


    $('.ui.form').form({
        inline: true,// 默认为false
        fields: {
            name: { //name值可以任意,不重复就行
                identifier: xxx,  //identifier 需要填写校验字段的name
                rules: [// rules指定校验的规则,值为一个数组,数组中每个元素为json格式,可以传入多个
                    {
                        type: 'typename', // 这里需要填写校验的类型。 可以选择semantic ui提供的,也可以用自己自定义,如何自定义在下面代码会演示
                        prompt: '提示信息' // 当校验失败是,可以给出相应的提示信息。
                    }
                ]
            }
        }
    })

inline值为false时的效果
在这里插入图片描述
在这里插入图片描述

表单校验的使用

  • regExp:进行正则表达式校验,需要传入一个值,即正则表达式。
  • mathch[identifier]:对比两个输入是否一样。identifier为对比对象的name。
  • empty:判断输入是否为空。
  • email:判断输入的email格式是否合法。
   $('.ui.form').form({
        // inline: true,
        fields: {
            password: {
                identifier: 'password',
                rules: [
                    {
                        type: 'regExp',  //
                        value: /^\w{8,16}$/i,
                        prompt: '密码不合法,请重新输入'
                    }
                ]
            },
            repeatpassword: {
                identifier: 'repeatpassword',
                rules: [
                    {
                        type: 'match[password]',
                        prompt: '密码不匹配'
                    }
                ]
            },
            nickname: {
                identifier: 'nickname',
                rules: [
                    {
                        type: 'empty',
                        prompt: '昵称不能为空'
                    }
                ]
            },
            username: {
                identifier: 'username',
                rules: [
                    {
                        type: 'regExp',
                        value: /^[a-zA-Z]\w{5,15}$/i,
                        prompt: '用户名不合法'
                    },
                    {
                        type: 'checkUsername',
                        prompt: '用户名已经被注册 <a href=[[@{/login}]]>点击登录?</a> '
                    }
                ]
            },
            email: {
                identifier: 'email',
                rules: [
                    {
                        type: 'email',
                        prompt: '请输入合法的邮箱'
                    },
                    {
                        type: 'checkEmail',
                        prompt: '邮箱已经注册, <a href=[[@{/login}]]>点击登录?</a> '
                    }
                ]
            },
            checkcode: {
                identifier: 'checkcode',
                rules: [
                    {
                        type: 'empty',
                        prompt: '请填写验证码'
                    },
                    {
                        type: 'checkCode',
                        prompt: '验证码填写错误'
                    }
                ]
            }
        }
    })


除了使用semantic UI官方提供的验证方法外,我们也可以自己定义,向上面代码中 checkUsernamecheckCode就是使用自定的规则。

自定义规则方式如下:

$.fn.form.settings.rules.开头,最后接一个方法名,然后定义一个匿名函数。在函数题中,编写判断逻辑。返回true表示验证通过,返回false则为验证失败。

在对邮箱进行校验时,要判断邮箱是否已经被注册了,所以在用ajax发送post请求时,要把异步给关闭了才行。

  $.fn.form.settings.rules.checkEmail = function () {
        var email = $('[name="email"]').val();
        // console.log(email);
        var flag = false;
        $.post({
            url: '[[@{/user/findEmail}]]',  // 获取验证信息的url,可以自行更换
            async: false, 
            data: {
                'email': email
            },
            success: function (data) {
                // console.log(data);
                flag = data.flag;
            }
        })
        return flag;
    }

$.fn.form.settings.rules.checkUsername = function () {
        var username = $('[name="username"]').val();
        // console.log(username);
        var flag = false;
        $.post({
            url: '[[@{/user/findUsername}]]',
            async: false,
            data: {
                'userName': username
            },
            success: function (data) {
                flag = data.flag;
            }
        })
        return flag;
    }

验证码的获取

验证是通过后端返回的一个图片信息。验证码图片是通过一个图片生成器的工具类生成验证码信息,然后返回给前端,验证码的值用session保存。

生成验证码的工具类是从网上找的,代码如下

package cn.jxj4869.blog.utils;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import javax.imageio.ImageIO;

public class CheckCodeGenerator {
    private static int width = 90;// 定义图片的width
    private static int height = 20;// 定义图片的height
    private static int codeCount = 4;// 定义图片上显示验证码的个数
    private static int xx = 15;
    private static int fontHeight = 18;
    private static  int codeY = 16;
    private static char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
            'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };

    /**
     * 生成一个map集合
     * code为生成的验证码
     * codePic为生成的验证码BufferedImage对象
     * @return
     */
    public static Map<String,Object> generateCodeAndPic() {
        // 定义图像buffer
        BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // Graphics2D gd = buffImg.createGraphics();
        // Graphics2D gd = (Graphics2D) buffImg.getGraphics();
        Graphics gd = buffImg.getGraphics();
        // 创建一个随机数生成器类
        Random random = new Random();
        // 将图像填充为白色
        gd.setColor(Color.WHITE);
        gd.fillRect(0, 0, width, height);

        // 创建字体,字体的大小应该根据图片的高度来定。
        Font font = new Font("Fixedsys", Font.BOLD, fontHeight);
        // 设置字体。
        gd.setFont(font);

        // 画边框。
        gd.setColor(Color.BLACK);
        gd.drawRect(0, 0, width - 1, height - 1);

        // 随机产生40条干扰线,使图象中的认证码不易被其它程序探测到。
        gd.setColor(Color.BLACK);
        for (int i = 0; i < 30; i++) {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int xl = random.nextInt(12);
            int yl = random.nextInt(12);
            gd.drawLine(x, y, x + xl, y + yl);
        }

        // randomCode用于保存随机产生的验证码,以便用户登录后进行验证。
        StringBuffer randomCode = new StringBuffer();
        int red = 0, green = 0, blue = 0;

        // 随机产生codeCount数字的验证码。
        for (int i = 0; i < codeCount; i++) {
            // 得到随机产生的验证码数字。
            String code = String.valueOf(codeSequence[random.nextInt(36)]);
            // 产生随机的颜色分量来构造颜色值,这样输出的每位数字的颜色值都将不同。
            red = random.nextInt(255);
            green = random.nextInt(255);
            blue = random.nextInt(255);

            // 用随机产生的颜色将验证码绘制到图像中。
            gd.setColor(new Color(red, green, blue));
            gd.drawString(code, (i + 1) * xx, codeY);

            // 将产生的四个随机数组合在一起。
            randomCode.append(code);
        }
        Map<String,Object> map  =new HashMap<String,Object>();
        //存放验证码
        map.put("code", randomCode);
        //存放生成的验证码BufferedImage对象
        map.put("codePic", buffImg);
        return map;
    }

    public static void main(String[] args) throws Exception {
        //创建文件输出流对象
        OutputStream out = new FileOutputStream(System.getProperty("user")+System.currentTimeMillis()+".jpg");
        Map<String,Object> map = CheckCodeGenerator.generateCodeAndPic();
        ImageIO.write((RenderedImage) map.get("codePic"), "jpeg", out);
        System.out.println("验证码的值为:"+map.get("code"));
    }
}

controller类

package cn.jxj4869.blog.controller;

import cn.jxj4869.blog.utils.CheckCodeGenerator;
import javax.imageio.ImageIO;
。。。。。。。。。。。。

/**

 * @author jxj4869
 * @since 2020-05-06
 */
@Controller
@RequestMapping("/user")
public class UserController {


    @GetMapping("/checkCode")
    public void checkCode(HttpServletResponse response, HttpSession session) throws IOException {

        Map<String, Object> map = CheckCodeGenerator.generateCodeAndPic();
        session.setAttribute("checkCode", map.get("code").toString());
        ImageIO.write((RenderedImage) map.get("codePic"), "PNG", response.getOutputStream());
    }


}

用户登录部分

在这里插入图片描述

<div class="ui five column centered stackable grid">
    <div class="ui  column m-margin-top-large " style="min-width: 480px">
        <div class="ui error message" th:if="${msg!=null}" th:text="${msg}"></div>
        <div class="ui container m-margin">
            <h2 class="ui center aligned header m-text m-teal">用户登录</h2>
        </div>
        <div class="ui container m-shadow-small">

            <form class="ui large form" method="post" action="#">
                <div class="ui  segment">
                    <div class="field">
                        <div class="ui left icon input">
                            <i class="user icon"></i>
                            <input type="text" name="username" placeholder="用户名">
                        </div>
                    </div>
                    <div class="field">
                        <div class="ui left icon input">
                            <i class="lock icon"></i>
                            <input type="password" name="password" placeholder="密码">
                        </div>
                    </div>
                    <div class="field container">

                        <div class="ui two column grid">
                            <div class="ui column">
                                <div class="ui left icon input">
                                    <i class="check icon"></i>
                                    <input type="text" name="checkcode" placeholder="验证码">
                                </div>
                            </div>
                            <div class="ui column">

                                <a href="javascript:void(0)" id="checkCode"><img src="static/img/checkcode.png"
                                                                                 th:src="@{/user/checkCode}"
                                                                                 class="rounded checkcode tooltip"
                                                                                 data-content="点击刷新验证码" alt=""></a>
                            </div>
                        </div>

                    </div>
                    <button id="login-btn" class="ui fluid large teal button" type="button">登 录</button>

                </div>

            </form>
        </div>


        <div class="ui container">
            <div class="ui bottom attached warning message container center aligned">
                <i class="icon help"></i>
                新用户? <a href="#" th:href="@{/register}">这里注册</a></div>
        </div>
    </div>

</div>

表单校验部分

   $.fn.form.settings.rules.checkCode = function () {
        var checkcode = $('[name="checkcode"]').val();
        var flag = false;
        $.post({
            url: '[[@{/user/checkCode}]]',
            async: false,
            data: {
                'checkCode': checkcode
            },
            success: function (data) {
                flag = data.flag;
            }
        })
        return flag;
    }


    $('.ui.form').form({
        inline:true,
        keyboardShortcuts:false,
        fields:{
            username:{
                identifier:'username',
                on:`blur`,
                rules:[
                    {
                        type:'empty',
                        prompt:'请输入用户名'
                    }
                ]
            },
            password:{
                identifier: 'password',
                rules:[
                    {
                        type:'empty',
                        prompt:'请输入密码'
                    }
                ]
            },
            checkcode:{
                identifier: 'checkcode',
                rules:[
                    {
                        type:'checkCode',
                        prompt:'验证码填写错误'
                    }
                ]
            },
        }
    })

完整源码

源码已上传到 github

猜你喜欢

转载自blog.csdn.net/qq_43058685/article/details/106089370