javaweb-注册页面的表单验证、判断用户名是否被注册(原生Ajax的了解)

发布时间 2023-03-22 21:16:19作者: 飞哥传书

资料来源于:B站尚硅谷JavaWeb教程(全新技术栈,全程实战) ,本人才疏学浅,记录笔记以供日后回顾
由于是多个视频内容混合在一起,因此只放了第一个链接
视频链接

知识点

  1. 注册页面表单验证
    1) <form>有一个事件 onsubmit ,
        onsubmit="return false" , 那么表单点击提交按钮时不会提交
        onsubmit="return true" ,  那么表单点击提交按钮时会提交

    2) 获取文档中某一个节点的方式:
        //DOM:Document 文档对象模型
        //var unameTxt = document.getElementById("unameTxt");
        //BOM:Browser 浏览器对象模型
        //document.forms[0].uname


  2. 原生的Ajax(了解)
    第一步: 客户端发送异步请求;并绑定对结果处理的回调函数
    1) <input type="text" name="uname" onblur="ckUname()"/> 当失去焦点时调用ckUname()
    2) 定义ckUname方法:
       - 创建XMLHttpRequest对象
       - XMLHttpRequest对象操作步骤:
         - open("GET",url,true)
         - onreadyStateChange 设置回调
         - send() 发送请求
       - 在回调函数中需要判断XMLHttpRequest对象的状态:
         readyState(0-4) , status(200)
    第二步:服务器端做校验,然后将校验结果响应给客户端

  3.详细解释
   Ajax : 异步的JavaScript and XML
    目的: 用来发送异步的请求,然后当服务器给我响应的时候再进行回调操作
    好处: 提高用户体验;局部刷新:降低服务器负担、减轻浏览器压力、减轻网络带宽压力
    开发步骤:
      1) 创建XMLHttpRequest
      2) 调用open进行设置:"GET" , URL , true
      3) 绑定状态改变时执行的回调函数 - onreadystatechange
      4) 发送请求 - send()
      5) 编写回调函数,在回调函数中,我们只对XMLHttpRequest的readystate为4的时候感兴趣
                                我们只对XMLHttpRequest的status为200的时候感兴趣

    0: (Uninitialized) the send( ) method has not yet been invoked.
    1: (Loading) the send( ) method has been invoked, request in progress.
    2: (Loaded) the send( ) method has completed, entire response received.
    3: (Interactive) the response is being parsed.
    4: (Completed) the response has been parsed, is ready for harvesting.

    0 - (未初始化)还没有调用send()方法
    1 - (载入)已调用send()方法,正在发送请求
    2 - (载入完成)send()方法执行完成,已经接收到全部响应内容
    3 - (交互)正在解析响应内容
    4 - (完成)响应内容解析完成,可以在客户端调用了

代码示例

regist.html代码

点击查看代码
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8" />
  <title>尚硅谷会员注册页面</title>
  <link type="text/css" rel="stylesheet" th:href="@{/static/css/style.css}" />
  <link rel="stylesheet" th:href="@{/static/css/register.css}"/>
  <style type="text/css">
    .login_form {
      height: 420px;
      margin-top: 25px;
    }
  </style>
  <script language="JavaScript" th:src="@{/static/script/regist.js}"></script>
</head>
<body>
<div id="login_header">
  <a href="../index.html">
    <img class="logo_img" alt="" th:src="@{/static/img/logo.gif}" />
  </a>
</div>

<div class="login_banner">
  <div class="register_form">
    <h1>注册尚硅谷会员</h1>
    <form th:action="@{/user.do}" method="post" onsubmit="return preRegist() ;">
      <input type="hidden" name="operate" value="regist"/>
      <div class="form-item">
        <div>
          <label>用户名称:</label>
          <input id="unameTxt" type="text" placeholder="请输入用户名" name="uname" value="hello2022" onblur="ckUname(this.value)"/>
        </div>
        <span id="unameSpan" class="errMess">用户名应为6~16位数字和字母组成</span>
      </div>
      <div class="form-item">
        <div>
          <label>用户密码:</label>
          <input id="pwdTxt" type="password" placeholder="请输入密码" name="pwd" value="ok"/>
        </div>
        <span id="pwdSpan" class="errMess">密码的长度至少为8位</span>
      </div>
      <div class="form-item">
        <div>
          <label>确认密码:</label>
          <input id="pwdTxt2" type="password" placeholder="请输入确认密码" value="ok"/>
        </div>
        <span id="pwdSpan2" class="errMess">密码两次输入不一致</span>
      </div>
      <div class="form-item">
        <div>
          <label>用户邮箱:</label>
          <input id="emailTxt" type="text" placeholder="请输入邮箱" name="email" value="bao@126.com"/>
        </div>
        <span id="emailSpan" class="errMess">请输入正确的邮箱格式</span>
      </div>
      <div class="form-item">
        <div>
          <label>验证码:</label>
          <div class="verify">
            <input type="text" name="verifyCode" placeholder="" />
            <img th:src="@{/kaptcha.jpg}" alt="" />
          </div>
        </div>
        <span class="errMess">请输入正确的验证码</span>
      </div>
      <button class="btn">注册</button>
    </form>
  </div>
</div>
<div id="bottom">
      <span>
        尚硅谷书城.Copyright &copy;2015
      </span>
</div>
</body>
</html>

regist.js代码

点击查看代码
function $(id){
    return document.getElementById(id);
}

function preRegist(){
    //用户名不能为空,而且是6~16位数字和字母组成
    var unameReg = /[0-9a-zA-Z]{6,16}/;
    var unameTxt = $("unameTxt");
    var uname = unameTxt.value ;
    var unameSpan = $("unameSpan");
    if(!unameReg.test(uname)){
        unameSpan.style.visibility="visible";
        return false ;
    }else{
        unameSpan.style.visibility="hidden";
    }

    //密码的长度至少为8位
    var pwdTxt = $("pwdTxt");
    var pwd = pwdTxt.value ;
    var pwdReg = /[\w]{8,}/; // /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,}$/;
    var pwdSpan = $("pwdSpan");
    if(!pwdReg.test(pwd)){
        pwdSpan.style.visibility="visible";
        return false ;
    }else{
        pwdSpan.style.visibility="hidden";
    }

    //密码两次输入不一致
    var pwd2 = $("pwdTxt2").value ;
    var pwdSpan2 = $("pwdSpan2") ;
    if(pwd2!=pwd){
        pwdSpan2.style.visibility="visible";
        return false ;
    }else{
        pwdSpan2.style.visibility="hidden";
    }

    //请输入正确的邮箱格式
    var email = $("emailTxt").value ;
    var emailSpan = $("emailSpan");
    var emailReg = /^[a-zA-Z0-9_\.-]+@([a-zA-Z0-9-]+[\.]{1})+[a-zA-Z]+$/;
    if(!emailReg.test(email)){
        emailSpan.style.visibility="visible";
        return false ;
    }else{
        emailSpan.style.visibility="hidden";
    }

    return true ;
}

//如果想要发送异步请求,我们需要一个关键的对象 XMLHttpRequest
var xmlHttpRequest ;

function createXMLHttpRequest(){
    if(window.XMLHttpRequest){
        //符合DOM2标准的浏览器 ,xmlHttpRequest的创建方式
        xmlHttpRequest = new XMLHttpRequest() ;
    }else if(window.ActiveXObject){//IE浏览器
        try{
            xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
        }catch (e) {
            xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP")
        }
    }
}

function ckUname(uname){
    createXMLHttpRequest();
    var url = "user.do?operate=ckUname&uname="+uname ;
    xmlHttpRequest.open("GET",url,true);
    //设置回调函数
    xmlHttpRequest.onreadystatechange = ckUnameCB ;
    //发送请求
    xmlHttpRequest.send();
}

function ckUnameCB(){
    if(xmlHttpRequest.readyState==4 && xmlHttpRequest.status==200){
        //xmlHttpRequest.responseText 表示 服务器端响应给我的文本内容
        //alert(xmlHttpRequest.responseText);
        var responseText = xmlHttpRequest.responseText ;
        // {'uname':'1'}
        //alert(responseText);
        if(responseText=="{'uname':'1'}"){
            alert("用户名已经被注册!");
        }else{
            alert("用户名可以注册!");
        }
    }
}


UserController类

检测用户名是否被注册

点击查看代码
package com.ypf.book.controller;


import com.ypf.book.pojo.Cart;
import com.ypf.book.pojo.User;
import com.ypf.book.service.CartItemService;
import com.ypf.book.service.UserService;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

public class UserController {

    private UserService userService ;
    private CartItemService cartItemService ;

    public String login(String uname , String pwd , HttpSession session){

        User user = userService.login(uname, pwd);
        if(user!=null){
            Cart cart = cartItemService.getCart(user);
            user.setCart(cart);
            session.setAttribute("currUser",user);
            return "redirect:book.do";
        }
        return "user/login";
    }

    public String regist(String verifyCode , String uname , String pwd , String email , HttpSession session , HttpServletResponse response) throws IOException {
        Object kaptchaCodeObj = session.getAttribute("KAPTCHA_SESSION_KEY");
        if(kaptchaCodeObj==null || !verifyCode.equals(kaptchaCodeObj)){
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");
            PrintWriter out = response.getWriter();
            //out.println("<script language='javascript'>alert('验证码不正确!');window.location.href='page.do?operate=page&page=user/regist';</script>");
            out.println("<script language='javascript'>alert('验证码不正确!');</script>");
            //return "user/regist";
            return "user/regist";
        }else{
            if(verifyCode.equals(kaptchaCodeObj)){
                userService.regist(new User(uname , pwd , email,0));
                return "user/login";
            }
        }
        return "user/login";
    }

    public String ckUname(String uname){
        User user = userService.getUser(uname);
        if(user!=null){
            //用户名已经被占用,不可以注册
            return "json:{'uname':'1'}";
            //return "ajax:1";
        }else{
            //用户名可以注册
            return "json:{'uname':'0'}";
            //return "ajax:0";
        }
    }
}

DispatcherServlet类

修改DispatcherServlet类的视图处理,添加对json格式的解析。

点击查看代码
package com.ypf.myssm.myspringmvc;

import com.ypf.myssm.ioc.BeanFactory;
import com.ypf.myssm.util.StringUtil;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

@WebServlet("*.do")
public class DispatcherServlet extends ViewBaseServlet {

    private BeanFactory beanFactory ;

    public DispatcherServlet(){
    }

    public void init() throws ServletException {
        super.init();
        //之前是在此处主动创建IOC容器的
        //现在优化为从application作用域去获取
        //beanFactory = new ClassPathXmlApplicationContext();
        ServletContext application = getServletContext();
        Object beanFactoryObj = application.getAttribute("beanFactory");
        if(beanFactoryObj!=null){
            beanFactory = (BeanFactory)beanFactoryObj ;
        }else{
            throw new RuntimeException("IOC容器获取失败!");
        }
    }

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置编码
        //request.setCharacterEncoding("UTF-8");
        //假设url是:  http://localhost:8080/pro15/hello.do
        //那么servletPath是:    /hello.do
        // 我的思路是:
        // 第1步: /hello.do ->   hello   或者  /fruit.do  -> fruit
        // 第2步: hello -> HelloController 或者 fruit -> FruitController
        String servletPath = request.getServletPath();
        servletPath = servletPath.substring(1);
        int lastDotIndex = servletPath.lastIndexOf(".do") ;
        servletPath = servletPath.substring(0,lastDotIndex);

        Object controllerBeanObj = beanFactory.getBean(servletPath);

        String operate = request.getParameter("operate");
        if(StringUtil.isEmpty(operate)){
            operate = "index" ;
        }

        try {
            Method[] methods = controllerBeanObj.getClass().getDeclaredMethods();
            for(Method method : methods){
                if(operate.equals(method.getName())){
                    //1.统一获取请求参数

                    //1-1.获取当前方法的参数,返回参数数组
                    Parameter[] parameters = method.getParameters();
                    //1-2.parameterValues 用来承载参数的值
                    Object[] parameterValues = new Object[parameters.length];
                    for (int i = 0; i < parameters.length; i++) {
                        Parameter parameter = parameters[i];
                        String parameterName = parameter.getName() ;
                        //如果参数名是request,response,session 那么就不是通过请求中获取参数的方式了
                        if("request".equals(parameterName)){
                            parameterValues[i] = request ;
                        }else if("response".equals(parameterName)){
                            parameterValues[i] = response ;
                        }else if("session".equals(parameterName)){
                            parameterValues[i] = request.getSession() ;
                        }else{
                            //从请求中获取参数值
                            String parameterValue = request.getParameter(parameterName);
                            String typeName = parameter.getType().getName();

                            Object parameterObj = parameterValue ;

                            if(parameterObj!=null) {
                                if ("java.lang.Integer".equals(typeName)) {
                                    parameterObj = Integer.parseInt(parameterValue);
                                }
                            }

                            parameterValues[i] = parameterObj ;
                        }
                    }
                    //2.controller组件中的方法调用
                    method.setAccessible(true);
                    Object returnObj = method.invoke(controllerBeanObj,parameterValues);

                    //3.视图处理
                    String methodReturnStr = (String)returnObj ;
                    if(methodReturnStr.startsWith("redirect:")){        //比如:  redirect:fruit.do
                        String redirectStr = methodReturnStr.substring("redirect:".length());
                        response.sendRedirect(redirectStr);
                    }else if(methodReturnStr.startsWith("json:")){
                        String jsonStr = methodReturnStr.substring("json:".length());
                        PrintWriter out = response.getWriter();
                        out.print(jsonStr);
                        out.flush();
                    }else{
                        super.processTemplate(methodReturnStr,request,response);    // 比如:  "edit"
                    }
                }
            }

            /*
            }else{
                throw new RuntimeException("operate值非法!");
            }
            */
        } catch (Exception e) {
            e.printStackTrace();
            throw new DispatcherServletException("DispatcherServlet出错了...");
        }
    }
}

// 常见错误: IllegalArgumentException: argument type mismatch