SSM项目之注册页面知识点整理

本文详细介绍了一个注册页面的设计与实现,包括图片验证码生成、前端与后端字段验证、密码加密及弹窗消息处理等关键技术点。

最近完成一个小项目,每次都会编写注册功能的实现。为了方便以后自己查阅和使用相同技术点的开发人员参考,记录一下注册页面所涉及知识点。

目录

1.图片验证码技术保护web应用

2.使用bootstrapvalidator 技术进行前端字段验证

3.后端使用JSR303进行字段验证

4.这里封装了两个js小方法

5.使用md5.js来对前端的密码加密

6.使用sweetalert进行弹框消息处理:


首先是页面的效果:

下面是重点知识点整理内容:

1.图片验证码技术保护web应用

后端生成验证码的工具类如下:

package com.justcs.utils;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;

/**
 * 生成随机的验证码图片工具
 */
public class RandomCodeUtil {

    public static final String RANDOMCODEKEY = "randomcode_key";//放到session中的key
    private Random random = new Random();
    private String randString = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";//随机产生的字符串

    private int width = 80;//图片宽
    private int height = 26;//图片高
    private int lineSize = 40;//干扰线数量
    private int stringNum = 4;//随机产生字符数量

    /**
     * 生成随机图片
     */
    public void getRandcode(HttpServletRequest request,
                            HttpServletResponse response) {
        HttpSession session = request.getSession();
        //BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类
        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);
        //产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作
        Graphics g = image.getGraphics();
        g.fillRect(0, 0, width, height);
        g.setFont(new Font("Times New Roman",Font.ROMAN_BASELINE,18));
        g.setColor(getRandColor(160, 200));
        //绘制干扰线
        for(int i=0;i<=lineSize;i++){
            drowLine(g);
        }
        //绘制随机字符
        String randomString = "";
        for(int i=1;i<=stringNum;i++){
            randomString=drowString(g,randomString,i);
        }
        session.removeAttribute(RANDOMCODEKEY);
        session.setAttribute(RANDOMCODEKEY, randomString);
        g.dispose();
        try {
            //将内存中的图片通过流动形式输出到客户端
            ImageIO.write(image, "JPEG", response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /*
     * 获得字体
     */
    private Font getFont(){
        return new Font("Fixedsys",Font.CENTER_BASELINE,18);
    }
    /*
     * 获得颜色
     */
    private Color getRandColor(int fc,int bc){
        if(fc > 255)
            fc = 255;
        if(bc > 255)
            bc = 255;
        int r = fc + random.nextInt(bc-fc-16);
        int g = fc + random.nextInt(bc-fc-14);
        int b = fc + random.nextInt(bc-fc-18);
        return new Color(r,g,b);
    }

    /*
     * 绘制字符串
     */
    private String drowString(Graphics g,String randomString,int i){
        g.setFont(getFont());
        g.setColor(new Color(random.nextInt(101),random.nextInt(111),random.nextInt(121)));
        String rand = String.valueOf(getRandomString(random.nextInt(randString.length())));
        randomString +=rand;
        g.translate(random.nextInt(3), random.nextInt(3));
        g.drawString(rand, 13*i, 16);
        return randomString;
    }
    /*
     * 绘制干扰线
     */
    private void drowLine(Graphics g){
        int x = random.nextInt(width);
        int y = random.nextInt(height);
        int xl = random.nextInt(13);
        int yl = random.nextInt(15);
        g.drawLine(x, y, x+xl, y+yl);
    }
    /*
     * 获取随机的字符
     */
    public String getRandomString(int num){
        return String.valueOf(randString.charAt(num));
    }
}

Controller层这样对外提供接口:

  /**
     * 输出验证码图片
     *
     * @param request
     * @param response
     */
    @RequestMapping("/checkcode")
    public void checkcode(HttpServletRequest request, HttpServletResponse response) {
        //设置相应类型,告诉浏览器输出的内容为图片
        response.setContentType("image/jpeg");
        //设置响应头信息,告诉浏览器不要缓存此内容
        response.setHeader("pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expire", 0);

        RandomCodeUtil randomValidateCode = new RandomCodeUtil();
        try {
            randomValidateCode.getRandcode(request, response);//输出图片方法
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

前端页面这样引用:

 <img src="/usr/checkcode" onclick="this.src=this.src+'?timestamp='+new Date().getTime()"
                                     class="valicodeimg" alt=""/>

2.使用bootstrapvalidator 技术进行前端字段验证

首先需要引用bootstrapvalidator的插件的js和css文件(前提是页面已经引用了jquery和bootstrap或者其他的框架:

<%-- 引入bootstrap表单验证资源 --%>
<link rel="stylesheet" href="../../bootstrapvalidator/css/bootstrapValidator.min.css"/>
<script src="../../bootstrapvalidator/js/bootstrapValidator.min.js" type="text/javascript"></script>

好了,下面列出我的注册页面的html结构:

<div class="panel">
                <div class="panel-heading text-left">
                    <div class="text-gray" style="font-weight: 600;line-height:40px;font-size:20px;">学生注册</div>
                </div>
                <div class="panel-body">
                    <form method="post" id="registform" class="form-horizontal" action="#">

                        <div class="form-group">
                            <label for="stuid" class="col-sm-3">学号</label>
                            <div class="col-md-7 col-sm-9">
                                <input type="text" class="form-control" name="stuid" id="stuid"
                                       placeholder="请输入您的学号(必填)">
                            </div>
                        </div>

                        <div class="form-group">
                            <label for="stuname" class="col-sm-3">姓名</label>
                            <div class="col-md-7 col-sm-9">
                                <input type="text" class="form-control" name="stuname" id="stuname"
                                       placeholder="请输入姓名(必填)">
                            </div>
                        </div>

                        <div class="form-group">
                            <label for="classno" class="col-sm-3">班级</label>
                            <div class="col-md-7 col-sm-9">
                                <input type="text" class="form-control" name="classno" id="classno"
                                       placeholder="请输入班级(必填)">
                            </div>
                        </div>

                        <div class="form-group">
                            <label for="stupwd" class="col-sm-3">输入密码</label>
                            <div class="col-md-7 col-sm-9">
                                <input type="password" class="form-control" name="stupwd" id="stupwd"
                                       placeholder="请输入账号密码(必填)">
                            </div>
                        </div>

                        <div class="form-group">
                            <label for="surepwd" class="col-sm-3">确认密码</label>
                            <div class="col-md-7 col-sm-9">
                                <input type="password" class="form-control" name="surepwd" id="surepwd"
                                       placeholder="请再次输入密码(必填)">
                            </div>
                        </div>

                        <div class="form-group">
                            <label for="tips" class="col-sm-3">备注</label>
                            <div class="col-md-7 col-sm-9">
                                <textarea class="form-control" id="tips" name="tips"
                                          placeholder="请输入备注(非必填项)"></textarea>
                            </div>
                        </div>

                        <div class="form-group">
                            <label for="valicode" class="col-sm-3">验证码</label>
                            <div class="col-md-4 col-sm-6">
                                <input type="text" class="form-control" id="valicode" name="valicode"
                                       placeholder="验证码(必填)"/>
                            </div>
                            <div class="col-md-4 col-sm-4">
                                <img src="/usr/checkcode" onclick="this.src=this.src+'?timestamp='+new Date().getTime()"
                                     class="valicodeimg" alt=""/>
                            </div>
                        </div>

                        <div style="margin-top:20px;margin-bottom:20px;">
                            <button
                                    type="button"
                                    id="subregistbtn"
                                    class="btn btn-success">
                                提交注册
                            </button>

                            &nbsp;&nbsp;&nbsp;&nbsp;

                            <button
                                    type="button"
                                    id="resetregist"
                                    class="btn btn-info">
                                重置表单
                            </button>
                        </div>

                        <br>
                        <span onclick="window.location.href='/'"
                              class="text-danger" style="text-decoration: underline;cursor: pointer;"><<返回登录</span>

                    </form>
                </div>
            </div>

下面编写js代码来完成前端验证的功能:

$('#registform').bootstrapValidator({
            message: "请输入有效的字段",
            fields: {
                "stuid": {
                    message: "学号非法",
                    validators: {
                        notEmpty: {
                            message: '学号不能为空'
                        },
                        stringLength: {
                            max: 20,
                            message: '学号最多20位'
                        }
                    }
                },
                "stuname": {
                    validators: {
                        notEmpty: {
                            message: '姓名不能为空'
                        },
                        stringLength: {
                            max: 40,
                            message: '姓名过长不能超过40个字'
                        }
                    }
                },
                "classno": {
                    validators: {
                        notEmpty: {
                            message: '班级不能为空'
                        },
                        stringLength: {
                            max: 50,
                            message: '班级过长不能超过50个字'
                        }
                    }
                },
                "stupwd": {
                    validators: {
                        notEmpty: {
                            message: '密码不能为空'
                        },
                        stringLength: {
                            min: 6,
                            max: 20,
                            message: '密码至少6位,最多20位'
                        },
                        different: {
                            field: 'stuid',
                            message: '密码不能和学号一致'
                        }
                    }
                },
                "surepwd": {
                    validators: {
                        notEmpty: {
                            message: '确认密码不能为空'
                        },
                        identical: {
                            field: 'stupwd',
                            message: '密码和确认密码不一致'
                        }
                    }
                },
                "valicode": {
                    validators: {
                        notEmpty: {
                            message: "验证码不能为空"
                        }
                    }
                }
            }
        });

在页面提交时候,需要验证字段,这样编写:

var bootstrapValidator = $("#registform").data('bootstrapValidator');
            bootstrapValidator.validate();
            if (bootstrapValidator.isValid()) {


}

3.后端使用JSR303进行字段验证

这里我的项目是maven构建的,在pom.xml引入包:

<!--jsr 303-->
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
        </dependency>
        <!-- hibernate validator-->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.2.0.Final</version>
        </dependency>

然后在项目中创建form对象RegistForm:

package com.justcs.form;

import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;

/**
 * 注册表单
 */
public class RegistForm {

    @NotEmpty(message = "学号不能为空")
    @Length(min = 1, max = 20, message = "学号最多20位")
    private String stuid;

    @NotEmpty(message = "学生的姓名不能为空")
    @Length(min = 1, max = 40, message = "姓名过长不能超过40个字")
    private String stuname;

    @NotEmpty(message = "班级不能为空")
    @Length(min = 1, max = 50, message = "班级过长不能超过50个字")
    private String classno;

    @NotEmpty(message = "密码不能为空")
    private String stupwd;

    @NotEmpty(message = "确认密码不能为空")
    private String surepwd;

    @Length(max = 100, message = "备注长度不能超过100个字")
    private String tips;

    @NotEmpty(message = "验证码不能为空")
    private String valicode;

    public String getStuid() {
        return stuid;
    }

    public void setStuid(String stuid) {
        this.stuid = stuid;
    }

    public String getStuname() {
        return stuname;
    }

    public void setStuname(String stuname) {
        this.stuname = stuname;
    }

    public String getClassno() {
        return classno;
    }

    public void setClassno(String classno) {
        this.classno = classno;
    }

    public String getStupwd() {
        return stupwd;
    }

    public void setStupwd(String stupwd) {
        this.stupwd = stupwd;
    }

    public String getSurepwd() {
        return surepwd;
    }

    public void setSurepwd(String surepwd) {
        this.surepwd = surepwd;
    }

    public String getTips() {
        return tips;
    }

    public void setTips(String tips) {
        this.tips = tips;
    }

    public String getValicode() {
        return valicode;
    }

    public void setValicode(String valicode) {
        this.valicode = valicode;
    }
}

其实前后端都需要验证的,前端使用来防君子,后端是为了堤防小人的。jsr303字段验证功能很丰富,拓展的还可以继续探索,通过正则表达式或者自定义验证注解。

然后在Controller层,这样来实现我们的字段验证:

 /**
     * 注册
     *
     * @return
     */
    @ResponseBody
    @RequestMapping("/doregist")
    public WebJSONResult doregist(@Valid @RequestBody RegistForm registForm,
                                  BindingResult result,
                                  HttpServletRequest request) {
        if (result.hasErrors()) {
            return WebJSONResult.errorMsgData("字段验证不通过",
                    WebJSONResult.convertErrorToMap(result));
        }
        // 验证码校验
        HttpSession session = request.getSession();
        String valicode = (String) session.getAttribute(RandomCodeUtil.RANDOMCODEKEY);
        if(StringUtils.equalsIgnoreCase(valicode, registForm.getValicode())){
            //TODO:执行录入操作
        } else {
            return WebJSONResult.errorMsg("验证码错误");
        }
        // 执行注册服务
        return WebJSONResult.ok();
    }

convertErrorToMap方法:

 public static Map convertErrorToMap(BindingResult result) {
        Map<String, Object> map = null;
        if (result != null) {
            map = new HashMap<>();
            List<FieldError> errors = result.getFieldErrors();
            for (FieldError fieldError : errors) {
                map.put(fieldError.getField(), fieldError.getDefaultMessage());
            }
        }
        return map;
    }

4.这里封装了两个js小方法

一个是能够将form表单转化为对象,一个是封装了jquery的ajax方法:

 // 序列化对象
    $.fn.serializeObject = function () {
        var o = {};
        // 将表单转为数组[{},{}...]
        var a = this.serializeArray();
        $.each(a, function () {
            // 如果对象中已有这个对象
            if (o[this.name]) {
                if (!o[this.name].push) {
                    o[this.name] = [o[this.name]];
                }
                o[this.name].push(this.value || '');
            } else { // 如果o中没有这个对象
                o[this.name] = this.value || '';
            }
        });
        return o;
    };

    // 执行ajax的post请求
    window.dopost = function (url, jsondata) {
        return new Promise(function (resolve, reject) {
            $.ajax({
                url: url,
                contentType: "application/json;charset=utf-8",
                dataType: "json",
                type: "post",
                data: JSON.stringify(jsondata),
                success: function (result) {
                    resolve(result);
                },
                error: function (result) {
                    console.log("->dopost异常...")
                }
            });
        });
    }

5.使用md5.js来对前端的密码加密

首先页面上引用md5.js的文件:

<script src="../../static/js/md5.js" type="text/javascript"></script>

然后在提交按钮这样编写:

 // 提交注册功能
        $("#subregistbtn").click(function () {
            var bootstrapValidator = $("#registform").data('bootstrapValidator');
            bootstrapValidator.validate();
            if (bootstrapValidator.isValid()) {
                var obj = $("#registform").serializeObject();
                console.log(obj);
                obj['stupwd'] = hex_md5(obj['stupwd']);
                obj['surepwd'] = hex_md5(obj['surepwd']);
                console.log(obj);
                dopost("/usr/doregist", obj).then(function (value) {
                    console.log(value);
                });
            }
        });

        $("#resetregist").click(function () {
            $('#registform').data('bootstrapValidator').resetForm(true);
        });

6.使用sweetalert进行弹框消息处理:

首先引入sweetalert的js文件:

<script src="../../static/js/sweetalert.min.js"></script>

 其次在用户注册完毕后弹出提示框:

 // 提交注册功能
        $("#subregistbtn").click(function () {
            var bootstrapValidator = $("#registform").data('bootstrapValidator');
            bootstrapValidator.validate();
            if (bootstrapValidator.isValid()) {
                var obj = $("#registform").serializeObject();
                console.log(obj);
                obj['stupwd'] = hex_md5(obj['stupwd']);
                obj['surepwd'] = hex_md5(obj['surepwd']);
                console.log(obj);
                dopost("/usr/doregist", obj).then(function (value) {
                    if (value.msg == "success") {
                        $("#resetregist").click();
                        $("#valicodeimg").attr("src", "/usr/checkcode");
                        swal({
                            text: "恭喜你注册成功!",
                            icon: "success",
                            button: "确定"
                        });
                    } else {
                        $("#valicodeimg").click();
                        swal({
                            text: value.msg,
                            icon: "error",
                            button: "确定"
                        })
                    }
                });
            }
        });

好了,注册页面的主要的通常面对的问题已经交代完毕了。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值