【途牛旅游项目】03 - 注册功能实现(aJax提交,正则表达式判断,BeanUtils封装和注册转换器)

注册功能分析图解

在这里插入图片描述

实现样式截图

在这里插入图片描述

实现注册功能

1. 创建注册业务的测试方法

//测试注册用户 - 保存用户信息  需要对username是否已经被注册过进行判断
    @Test
    public void test02() {
    
    
        UserService userService = new UserService();

        User user= new User(null,"register123","ABC123456",new Date(),"注册昵称","男","17878782828","[email protected]","N","codeNumber");
//        user.setUsername("strive_gf");
//        user.setPassword("ABC123456");
        int code = userService.register(user);

        if(code == 1){
    
    
            System.out.println("注册成功");
        }else if(code == 0){
    
    
            System.out.println(user.getUsername()+"已经被注册过了,请更换用户名");
        }
    }

2. 创建业务层UserService的注册方法

public int register(User user) {
    
    

        //查找username是否存在,存在就返回错误,不能注册
        User u = userDao.findByUserName(user.getUsername());
        if(u == null){
    
    
            user.setStatus("N");//注册成功,但是设置为未激活,需要去激活
            //保存用户注册数据
            userDao.saveUser(user);
            return 1;//未存在,可以注册
        }else {
    
    
            return 0;//已存在,不可注册
        }
    }

3. 创建dao层接口方法

public interface UserDao {
    
    
    //通过usernmae查询user是否存在
    User findByUserName(String username);

    //保存用户注册数据,添加用户
    void saveUser(User user);
}

4. 创建dao的映射文件xml

<!--注册时通过usernmae查询是否被注册过-->
    <select id="findByUserName" parameterType="string" resultType="com.xgf.bean.User">
         select uid,username,password,name,birthday,sex,telephone,email,status,code
          from tab_user
          where username = #{username}
    </select>

    <!--保存用户注册数据,添加用户-->
    <insert id="saveUser" parameterType="com.xgf.bean.User" >
        insert into tab_user values
        (null,#{username},#{password},#{name},#{birthday},#{sex},#{telephone},#{email},#{status},#{code})
    </insert>

5. 测试dao层的findByUserName方法

//对user的dao进程测试
public class TestUserDao {
    
    
    //通过工具类获取userdao的bean
    private static UserDao userDao = GetDaoUtils.getMapper(UserDao.class);

    //测试findByUserName方法,查询usermane是否已存在
    @Test
    public void test01(){
    
    
        User user = userDao.findByUserName("strive_gf");
        if(user == null){
    
    
            System.out.println("username未注册,可以注册");
        }else{
    
    
            System.out.println("username已注册,请更换");
        }
    }
}

6. 测试注册TestUserService.test02()

//运行结果
//第一步,查询username是否已经被注册
Preparing: select uid,username,password,name,birthday,sex,telephone,email,status,code from tab_user where username = ?
Parameters: register123(String)
  Total: 0

日志返回结果:0条记录被查到,证明该username没有被注册,可以注册

//第二步调用saveUser方法保存注册的用户
Preparing: insert into tab_user values (null,?,?,?,?,?,?,?,?,?)
Parameters: register123(String), ABC123456(String), 注册昵称(String), 2020-10-08 09:12:12.281(Timestamp), 男(String), 17878782828(String), [email protected](String), N(String), codeNumber(String)
  Updates: 1

日志返回结果:更新一条记录,也就是增加成功,注册成功。
在这里插入图片描述

7. 编写前端jsp注册界面

  这里有用正则表达式对用户名、密码、邮箱进行正则判断

  • 校验用户名 /^\w{8,20}$/ 单词字符,长度8到20位
  • 校验密码 /^\w{8,20}$/ 单词字符,长度8到20位
  • 校验邮箱 = /^\w+@\w+.\w+$/ 邮箱 [email protected]

7.1 前端页面

<!--注册表单-->
            <form id="registerForm">

                <!--提交处理请求的标识符-->
                <input type="hidden" name="action" value="register">
                <table style="margin-top: 25px;">
                    <tr>
                        <td class="td_left">
                            <label for="username">用户名</label>
                        </td>
                        <td class="td_right">
                            <input type="text" id="username" name="username" placeholder="请输入账号">
                        </td>
                    </tr>
                    <tr>
                        <td class="td_left">
                            <label for="password">密码</label>
                        </td>
                        <td class="td_right">
                            <input type="text" id="password" name="password" placeholder="请输入密码">
                        </td>
                    </tr>
                    <tr>
                        <td class="td_left">
                            <label for="email">Email</label>
                        </td>
                        <td class="td_right">
                            <input type="text" id="email" name="email" placeholder="请输入Email">
                        </td>
                    </tr>
                    <tr>
                        <td class="td_left">
                            <label for="name">姓名</label>
                        </td>
                        <td class="td_right">
                            <input type="text" id="name" name="name" placeholder="请输入真实姓名">
                        </td>
                    </tr>
                    <tr>
                        <td class="td_left">
                            <label for="telephone">手机号</label>
                        </td>
                        <td class="td_right">
                            <input type="text" id="telephone" name="telephone" placeholder="请输入您的手机号">
                        </td>
                    </tr>
                    <tr>
                        <td class="td_left">
                            <label for="sex">性别</label>
                        </td>
                        <td class="td_right gender">
                            <input type="radio" id="sex" name="sex" value="" checked><input type="radio" name="sex" value=""></td>
                    </tr>
                    <tr>
                        <td class="td_left">
                            <label for="birthday">出生日期</label>
                        </td>
                        <td class="td_right">
                            <input type="date" id="birthday" name="birthday" placeholder="年/月/日">
                        </td>
                    </tr>
                    <tr>
                        <td class="td_left">
                            <label for="check">验证码</label>
                        </td>
                        <td class="td_right check">
                            <input type="text" id="inputCheckCode" name="inputCheckCode" class="check">
                            <img src="checkCodeServlet" height="32px" alt="看不清?点我换一换" onclick="changeCheckCode(this)">
                            <script type="text/javascript">
                                //图片点击事件,点击更换验证码
                                function changeCheckCode(img) {
     
     
                                    img.src="checkCodeServlet?"+new Date().getTime();//添加时间戳
                                }
                            </script>
                        </td>
                    </tr>
                    <tr>
                        <td class="td_left">
                        </td>
                        <td class="td_right check">
                            <input type="submit" class="submit" value="注册">
                            <span id="msg" style="color: red;"></span>
                        </td>
                    </tr>
                </table>
            </form>

7.2 前端js脚本,进行输入验证,ajax提交

这里通过表单序列化$("#registerForm").serialize()方法,向后台输送表单内容。
这里只是简单的正则表达式验证,以后用框架就行。

<script type="text/javascript">
        //输入校验
        var usernameFlag;
        var passwordFlag;
        var emailFlag;
        function checkUsername() {
    
    

            //判断一下账号输入是否合法
            var username = $("#username").val();
            //8-20位字符或数字
            var reg = /^\w{8,20}$/;
            usernameFlag = reg.test(username);
            if (usernameFlag) {
    
    
                //符合条件,提示username可用,清空前面的报错
                $("#username").css("border", "");
                $("#errorMsg").html("");
            } else {
    
    
                //修改边框,提示不可用
                $("#username").css("border", "3px solid red");
                $("#errorMsg").html("用户名必须是8-20位数字和字母组合");
            }
            return usernameFlag;
        }

        function checkPassword() {
    
    
            //判断一下密码输入是否合法
            var password = $("#password").val();
            var reg = /^\w{8,20}$/;
            passwordFlag = reg.test(password);
            if (passwordFlag) {
    
    
                $("#errorMsg").html("");
                //不提示
                $("#password").css("border", "");
            } else {
    
    
                //提示
                $("#password").css("border", "3px solid red");
                if(usernameFlag){
    
    //用户名输入正确才显示密码错误
                    $("#errorMsg").html("密码必须是8-20位数字和字母组合");
                }

            }
            return passwordFlag;
        }

        function checkEmail() {
    
    
            //判断一下密码输入是否合法
            var email = $("#email").val();
            var reg = /^\w+@\w+\.\w+$/;
            emailFlag = reg.test(email);
            if (emailFlag) {
    
    
                $("#errorMsg").html("");
                //不提示,无边框
                $("#email").css("border", "");
            } else {
    
    
                //提示
                $("#email").css("border", "3px solid red");
                if(usernameFlag && passwordFlag){
    
    //如果用户名和密码都正确才显示邮箱错误,前面的优先显示
                    $("#errorMsg").html("邮箱输入不正确");
                }
            }
            return emailFlag;
        }

        //页面初始化执行
        $(function () {
    
    
            //账号密码 手机号 邮箱 -> 通过正则判断,是否合法
            //格式正确不作提示,如果错误将边框改成红色
            $("#username").blur(checkUsername)
            $("#password").blur(checkPassword)
            $("#email").blur(checkEmail)

            $("#registerForm").submit(function () {
    
    
                if(!usernameFlag){
    
    
                    $("#errorMsg").html("用户名必须是8-20位数字和字母组合");
                }else if(!passwordFlag){
    
    
                    $("#errorMsg").html("密码必须是8-20位数字和字母组合");
                }else if(!emailFlag){
    
    
                    $("#errorMsg").html("邮箱输入不正确")
                }
                //ajax提交
                if (checkUsername() && checkPassword() && checkEmail()) {
    
    
                    //使用serialize()序列化方法,将整个表单序列化成json字符串发送给后台
                    $.post("RegisterServlet", $("#registerForm").serialize(),
                        function (data) {
    
    
                            //{code:1,data:成功}
                            if (data.code == 1) {
    
    
                                window.location = "login.jsp";
                            } else {
    
    
                                //注册失败,错误提示信息
                                $("#errorMsg").html(data.data);
                            }
                        }, "json");
                }
                return false;
            })
        });
    </script>

8. 创建注册servlet,获取参数通过 BeanUtils封装对象

//登录servlet
@WebServlet("/RegisterServlet")
public class RegisterServlet extends HttpServlet {
    
    

	//beanUtils是不能自动的将String转换为日期Date类型,通过serialize序列化方法提交表单,取出是字符串形式,需要进行格式转换,不然的话不能封装成bean对象
    //BeanUtils不支持自动将String向Date数据类型转换
    //BeanUtils格式转换器,静态代码块,在加载的时候自动执行,而且只执行一次
    static {
    
    
        //ConvertUtils.register()方法,将String转Date的转换器注册给beanUtils
        //一般写在静态代码块中(只执行一次),或者在项目启动的时候自己注册(通过监听器实现)
        //将转换器注册到BeanUtils中
        ConvertUtils.register(new Converter() {
    
    

            public Object convert(Class type, Object value) {
    
    
                //将yyyy-MM-dd格式的字符串转换为Date数据类型
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                try {
    
    
                    return simpleDateFormat.parse(value.toString());
                } catch (ParseException e) {
    
    
                    e.printStackTrace();
                }
                return null;
            }
        }, Date.class);
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    


        UserService userService = new UserService();
        HttpSession session = request.getSession();//获取session对象,里面主要是验证码和当前user
        Msg msg = new Msg();//提示信息

        //用户输入的验证码
        String inputCheckCode = request.getParameter("inputCheckCode");
        //从session中获取系统当前生成的验证码
        String verificationCode = (String) session.getAttribute("verificationCode");
        System.out.println("RegisterServlet \t\t inputCheckCode : " + inputCheckCode + " ;\t verificationCode : " + verificationCode);

        //inputCheckCode 与 verificationCode
        //相同表示验证码不正确,将提示信息写到页面的错误提示
        if (inputCheckCode == null || !inputCheckCode.equalsIgnoreCase(verificationCode)) {
    
    
            //验证码不看大小写
            msg.setCode(-1);
            msg.setData("验证码输入出错,请重新输入验证码");

            //将字符串转换为json数据格式返回给浏览器
            String json = new ObjectMapper().writeValueAsString(msg);
            response.getWriter().println(json);
            return; //返回不继续执行
        }

        //获取请求参数
        Map<String, String[]> map = request.getParameterMap();
        //当前登录用户
        User registerUser = new User();
        try {
    
    
            //参1 javaBean 参2 map 封装bean对象
            BeanUtils.populate(registerUser, map);//将map里面所有的参数赋值给javaBean(login就是输入的username和password)
        } catch (IllegalAccessException e) {
    
    
            e.printStackTrace();
        } catch (InvocationTargetException e) {
    
    
            e.printStackTrace();
        }

        //调用service处理参数,注册业务
        int code = userService.register(registerUser);
        //响应给浏览器 ajax 是响应json给浏览器就可以
        msg.setCode(code);//设置code

        if (code == 1) {
    
    
            msg.setData("注册成功,跳转登录界面");
            //从session中删除生成的验证码 不移除的话可能会覆盖新的验证码
            session.removeAttribute("verificationCode");
        } else if(code == 0){
    
    
            msg.setData(registerUser.getUsername()+"已注册,请更换用户名");
        }else {
    
    
            msg.setData("注册失败");
        }

        //将字符串转成json数据格式,返回给浏览器显示提示信息msg
        String json = new ObjectMapper().writeValueAsString(msg);
        response.getWriter().println(json);
    }
}
//beanUtils不能自动的将String转换为日期Date类型,通过serialize序列化方法进行的,取出是字符串形式,需要进行格式转换
    //BeanUtils不支持自动将String向Date数据类型转换
    //BeanUtils格式转换器
    static {
    
    
        //静态代码块,在加载的时候自动执行,而且只执行一次
        //ConvertUtils.register()方法,将string转date的转换器注册给beanUtils
        //一般写在静态代码块中(只执行一次),或者在项目启动的时候自己注册(通过监听器实现)
        //将转换器注册到BeanUtils中
        ConvertUtils.register(new Converter() {
    
    

            public Object convert(Class type, Object value) {
    
    
                //将yyyy-MM-dd格式的字符串转换为Date数据类型
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                try {
    
    
                    return simpleDateFormat.parse(value.toString());
                } catch (ParseException e) {
    
    
                    e.printStackTrace();
                }
                return null;
            }
        }, Date.class);
    }

BeanUtils将接收String转换为Date数据类型【***】

  BeanUtils是不能自动的将String转换为日期Date类型,通过serialize序列化方法提交表单,取出是字符串形式,需要进行格式转换,不然的话不能封装成bean对象。
  BeanUtils不支持自动将String向Date数据类型转换,可以通过ConvertUtils.register()方法,将String转Date的转换器注册给beanUtils,这个方法一般写在静态代码块中(只执行一次),或者在项目启动的时候自己注册(通过监听器实现)

    //BeanUtils格式转换器,静态代码块,在加载的时候自动执行,而且只执行一次
    static {
    
    
        //将转换器注册到BeanUtils中
        ConvertUtils.register(new Converter() {
    
    

            public Object convert(Class type, Object value) {
    
    
                //将yyyy-MM-dd格式的字符串转换为Date数据类型
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                try {
    
    
                    return simpleDateFormat.parse(value.toString());
                } catch (ParseException e) {
    
    
                    e.printStackTrace();
                }
                return null;
            }
        }, Date.class);
    }

9. 运行结果

错误输入提示:
在这里插入图片描述
输入符合要求的参数进行注册:
在这里插入图片描述

查看网络参数,传送给后台的请求参数:

在这里插入图片描述
注册成功跳转登录界面
在这里插入图片描述
测试登录,显示还未激活,下一篇,用邮箱激活账户:
在这里插入图片描述

10. 代码仓库地址

https://github.com/strive-xgf/SSM/commit

猜你喜欢

转载自blog.csdn.net/qq_40542534/article/details/108959217