验证用户名是否存在-前后端

效果

前端

1.HTML 页面的设计

2.JS 的点击事件的绑定,并通过 XHR(XmlHttpRequest 对象,发送 JSON 格式的数据到服务器 TomCat)

//验证用户名是否存在
function verifyUserName(event) {
  // 1.得到表单提交的数据
  //用户名
  var uname = document.getElementById("uname").value;
  //验证是否得到表单数据
  // alert("uname"+uname)

  //2.创建XmlHttpRequest对象
  var xhr = new XMLHttpRequest();
  //3.使用open方法,请求数据
  // 参数1:请求方式
  // 参数2:请求的url地址
  // 参数3:同步:false 异步:true
  // 注意访问的地址:
  xhr.open("GET", "http://localhost:8080/user/checkUserServlet?username="+uname+
           "&pwd=&email=", true)
  //发送http请求
  //get请求不需要田填写数据
  //post请求则需要填写数据
  xhr.send();

}

3. 当点击验证按钮的时候(onclock)触发verifyUserName 函数并通过表单的 action 路径提交到 Tomcat 服务器上

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册页面</title>
    <!--    引入user.js-->
    <script type="text/javascript" src="user.js"></script>
</head>
<body>
    <h1>用户注册</h1>
    <form method="get" action="/user/checkUserServlet" name="">
        用户名字:<input type="text" name="username" id="uname">
        <button type="button" id="ver_btn" onclick="verifyUserName()">验证用户名</button>
<!--        验证用户名的提示标签-->
        <span id="verificationUser"></span><br>
        用户密码:<input type="text" name="pwd" id="pwd"><br>
        电子邮件:<input type="text" name="email" id="email"><br>
        <input type="submit" value="用户注册" id="registerBtn">
    </form>
</body>
</html>

后端:

1. 配置 Tomcat,启动 web 服务

TomCat 会将 Http 请求封装成 Request 对象给 Servlet 对象

Servlet 对象就可以得到前端提交的 JSON 格式的数据

然后将得到的 JSON 格式的数据转为 JavaBean 进行解析

得到用户名

package servlet; /**
 * ClassName: ${NAME}
 * Package: ${PACKAGE_NAME}
 * Description:
 *
 * @Author 王文福
 * @Create 2024/1/13 20:32
 * @Version 1.0
 */

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet(name = "checkUserServlet", value = "/checkUserServlet")
public class checkUserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //System.out.println("checkUser被调用");
        //1.得到表单提交的数据(uname)-注意该username为请求地址的参数
        String username = request.getParameter("username");
        System.out.println("username=" + username);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

MySql 数据库

根据该用户名去数据库中查询该用户的信息

如果该用户存在 则返回该用户的信息,得到 1 个 JavaBean 对象

并将该 JavaBean 对象转为 JSON 格式的数据返回给前端

如果该用户不存在 则直接返回 1 个空的 JSON 格式的数据

1. 表的设计
#创建数据库
#默认校对规则:utf-8_general_ci [不区分大小写]
#校对规则utf8_bin 区分大小写
CREATE DATABASE user CHARACTER SET utf8 COLLATE utf8_bin;


#使用数据库
use `user`;



#创建表
#comment注释,default默认
CREATE TABLE IF NOT EXISTS `user`(
  `id` INT(4) NOT NULL AUTO_INCREMENT COMMENT '编号',   
  `uname` VARCHAR(30) NOT NULL DEFAULT '' COMMENT '用户名',
  `pwd` VARCHAR(30) NOT NULL DEFAULT '' COMMENT '密码',
  `email` VARCHAR(30) NOT NULL DEFAULT '' COMMENT '邮箱',
  PRIMARY KEY(`id`) #主键id
  # INNODB引擎
  # CHARSET字符集(保存字符的大小,gbk1个字符占2个字节,utf-8,1个字符占3个字节)
  # 校验规则:utf8_bin(区分大小写)
)ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE utf8_bin


#添加数据
INSERT INTO `user`(`id`,`uname`,`pwd`,`email`)
		VALUES(1,'tom','123','1234567890@qq.com'),
					(2,'jack','123','1234567890@qq.com')
#查询表
SELECT * FROM `user` 

IDEA

1. 分层设计

2.导入德鲁伊库库

3.导入德鲁伊工具类
package utils;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import java.io.FileInputStream;
import java.sql.ResultSet;
import java.sql.SQLException;


import javax.sql.DataSource;

import java.sql.Connection;

import java.sql.Statement;
import java.util.Properties;


/**
 * ClassName: JDBCUtilsByDruid
 * Package: utils
 * Description:
 *
 * @Author 王文福
 * @Create 2024/1/13 21:19
 * @Version 1.0
 */
public class JDBCUtilsByDruid {
    private static DataSource ds;

    //在静态代码块完成 ds初始化
    static {
        Properties properties = new Properties();
        try {
            properties.load(new FileInputStream("src\\druid.properties"));
            ds = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    //编写getConnection方法
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }

    //关闭连接, 老师再次强调: 在数据库连接池技术中,close 不是真的断掉连接
    //而是把使用的Connection对象放回连接池
    public static void close(ResultSet resultSet, Statement statement, Connection connection) {

        try {
            if (resultSet != null) {
                resultSet.close();
            }
            if (statement != null) {
                statement.close();
            }
            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

}
4. 配置德鲁伊文件-src 文件夹下
#key=value
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/user?rewriteBatchedStatements=true
#url=jdbc:mysql://localhost:3306/girls
username=root
password=abc123
#initial connection Size
initialSize=10
#min idle connecton size
minIdle=5
#max active connection size
maxActive=20
#max wait time (5000 mil seconds)
maxWait=5000
5.在 dao 文件夹下导入 BasicDAO
package dao;

import utils.JDBCUtilsByDruid;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;


/**
 * @author 韩顺平
 * @version 1.0
 * 开发BasicDAO , 是其他DAO的父类
 */
public class BasicDAO<T> { //泛型指定具体类型

    private QueryRunner qr = new QueryRunner();

    //开发通用的dml方法, 针对任意的表
    public int update(String sql, Object... parameters) {

        Connection connection = null;

        try {
            connection = JDBCUtilsByDruid.getConnection();
            int update = qr.update(connection, sql, parameters);
            return update;
        } catch (SQLException e) {
            throw new RuntimeException(e); //将编译异常->运行异常 ,抛出
        } finally {
            JDBCUtilsByDruid.close(null, null, connection);
        }

    }

    //返回多个对象(即查询的结果是多行), 针对任意表

    /**
     * @param sql        sql 语句,可以有 ?
     * @param clazz      传入一个类的Class对象 比如 Actor.class
     * @param parameters 传入 ? 的具体的值,可以是多个
     * @return 根据Actor.class 返回对应的 ArrayList 集合
     */
    public List<T> queryMulti(String sql, Class<T> clazz, Object... parameters) {

        Connection connection = null;
        try {
            connection = JDBCUtilsByDruid.getConnection();
            return qr.query(connection, sql, new BeanListHandler<T>(clazz), parameters);

        } catch (SQLException e) {
            throw new RuntimeException(e); //将编译异常->运行异常 ,抛出
        } finally {
            JDBCUtilsByDruid.close(null, null, connection);
        }

    }

    //查询单行结果 的通用方法
    public T querySingle(String sql, Class<T> clazz, Object... parameters) {

        Connection connection = null;
        try {
            connection = JDBCUtilsByDruid.getConnection();
            return qr.query(connection, sql, new BeanHandler<T>(clazz), parameters);

        } catch (SQLException e) {
            throw new RuntimeException(e); //将编译异常->运行异常 ,抛出
        } finally {
            JDBCUtilsByDruid.close(null, null, connection);
        }
    }

    //查询单行单列的方法,即返回单值的方法

    public Object queryScalar(String sql, Object... parameters) {

        Connection connection = null;
        try {
            connection = JDBCUtilsByDruid.getConnection();
            return qr.query(connection, sql, new ScalarHandler(), parameters);

        } catch (SQLException e) {
            throw new RuntimeException(e); //将编译异常->运行异常 ,抛出
        } finally {
            JDBCUtilsByDruid.close(null, null, connection);
        }
    }
}


6.新建 JavaBean

在 domain 文件下新建 user

该对象的属性与表设计的字段一致

package domain;

/**
 * ClassName: user
 * Package: domain
 * Description:
 * JavaBean-user
 *
 * @Author 王文福
 * @Create 2024/1/13 21:36
 * @Version 1.0
 */
public class user {
    private Integer id;
    private String uname;
    private String pwd;
    private String email;

    //提供无参构造器,主要是为了能通过反射创建user实例
    
    public user() {
    }
	//有参构造器可以不提供
    public user(Integer id, String uname, String pwd, String email) {
        this.id = id;
        this.uname = uname;
        this.pwd = pwd;
        this.email = email;
    }

    //提供get、set方法,提供重写toString方法
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "user{" + "id=" + id + ", uname='" + uname + '\'' + ", pwd='" + pwd + '\'' + ", email='" + email + '\'' + '}';
    }
}
7.新建 UserDAO

目录:DAO

package dao;

import domain.User;

/**
 * ClassName: UserDAO
 * Package: dao
 * Description:
 *
 * @Author 王文福
 * @Create 2024/1/13 21:47
 * @Version 1.0
 */
public class UserDAO extends BasicDAO<User> {
    //继承后,可以提高代码的复用性
    //使用父类BasicDAO提高的增删改查的功能
}
8.新建 UserService 层

目录:service——业务层

package service;

import dao.UserDAO;
import domain.User;

/**
 * ClassName: UserService
 * Package: service
 * Description:
 *
 * @Author 王文福
 * @Create 2024/1/13 22:00
 * @Version 1.0
 */
public class UserService {
    //得到UserDAO对象,
    private UserDAO userDAO = new UserDAO();

    //查询用户名
    public User getUserByUname(String uname) {
        User user = userDAO.querySingle("select * from user where uname =?", 
                                        User.class, uname);
        return user;
    }
}
9.新建测试类
package test;

import domain.User;
import service.UserService;

/**
 * ClassName: Test
 * Package: test
 * Description:
 *
 * @Author 王文福
 * @Create 2024/1/13 22:34
 * @Version 1.0
 */
public class Test {
    public static void main(String[] args) {
        String name = "tom";
        UserService userService = new UserService();
        //传入查询字符串
        User user = userService.getUserByUname(name);
        System.out.println(user);
    }
}

注意:

如果是通过 Java 创建的 Web 项目则需要将

JDBCUtilsByDruid 类中的 Properties 配置文件的路径修改为如下

如果是 Maven 项目,

则需要添加如下依赖,并确保 druid.properties 文件目录文件在 src/main/resources 文件夹下,然后重新构建项目即可

<build>


  <resources>
    <resource>
      <directory>
        src/main/resources
      </directory>
      <filtering>false</filtering>
      <includes>
        <include>**/*.properties</include>

      </includes>
    </resource>
  </resources>


</build>
9.CheckUserServlet
package servlet; /**
 * ClassName: ${NAME}
 * Package: ${PACKAGE_NAME}
 * Description:
 *
 * @Author 王文福
 * @Create 2024/1/13 20:32
 * @Version 1.0
 */

import com.alibaba.fastjson.JSON;
import domain.User;
import service.UserService;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet(name = "CheckUserServlet", value = "/checkUserServlet")
public class CheckUserServlet extends HttpServlet {
    //定义UserService属性
    private UserService userService = new UserService();

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //System.out.println("checkUser被调用");
        //1.得到表单提交的数据(uname)-注意该uname为请求地址的参数
        String username = request.getParameter("username");
        //从数据库中查询该用户
        User user = userService.getUserByUname(username);
        //如果该用户不为空
        if (user != null) {
            //将JavaBean转为JSON格式的字符串
            String userJSON = JSON.toJSONString(user);
            //设置响应头
            response.setContentType("text/plain");
            //将JSON格式的数据发送给浏览器/客户端
            response.getWriter().write(userJSON);
        } else {
            //返回空的JSON格式的字符串
            response.getWriter().write("");
        }

    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

前端

//验证用户名是否存在
function verifyUserName(event) {
    // 1.得到表单提交的数据
    //用户名
    var uname = document.getElementById("uname").value;
    //验证是否得到表单数据
    // alert("uname"+uname)

    //2.创建XmlHttpRequest对象
    var xhr = new XMLHttpRequest();
    //该事件表示,可以去指定1个函数,当数据变化,会触发onreadystatechange
    //每当xhr对象的readyState改变时,就会触发onreadystatechange事件
    xhr.onreadystatechange = function () {
        //如果请求已经完成,并且已经就绪,并且状态码是200

        if (xhr.readyState == 4 && xhr.status == 200) {
            //得到JSON字符串
            var responseText = xhr.responseText;
            console.log(responseText);
            //判断得到的JSON字符是否为空
            if (responseText != "") {
                //该用户存在
                var verificationUser = document.getElementById("verificationUser");
                // verificationUser.css("color","red");
                verificationUser.innerHTML = "该用户存在"
                //显示用户的信息
                document.getElementById("userData").innerHTML = responseText;
            } else {
                //该用户不存在
                var verificationUser = document.getElementById("verificationUser");
                // verificationUser.css("color","red");
                verificationUser.innerHTML = "该用户不存在";
                document.getElementById("userData").innerHTML = "";
            }
        }
    }
    //3.使用open方法,请求数据
    // 参数1:请求方式
    // 参数2:请求的url地址
    // 参数3:同步:false 异步:true
    xhr.open("GET", "http://localhost:8080/user/checkUserServlet?username=" + uname + "&pwd=&email=#", true)
    //发送http请求
    //get请求不需要田填写数据
    //post请求则需要填写数据
    xhr.send();

}

使用 JQuery 的 Ajax 完成处理前面的案例

1.创建新的 Servlet 对象

package servlet; /**
 * ClassName: ${NAME}
 * Package: ${PACKAGE_NAME}
 * Description:
 *
 * @Author 王文福
 * @Create 2024/1/14 13:24
 * @Version 1.0
 */

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet(name = "CheckUserServlet2", value = "/CheckUserServlet2")
public class CheckUserServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("CheckUserServlet2");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

2.创建新的 register02.html

用户 点击后跳转到 Tomcat 的新的 Serlvet 对象的地址 CheckUserServlet2

注意:按钮的类型必须是 button 不能是 submit,否则 响应数据回来后会不在原来的登录界面从而导致的数据收到了但是请求失败

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册页面</title>
    <!--    引入Jquery.js-->
    <script type="text/javascript" src="jquery-3.6.0.min.js"></script>
    <!--    引入user2.js-->
    <script type="text/javascript" src="user2.js"></script>
</head>
<body>
<h1>用户注册JQuery+Ajax</h1>
<form method="POST" action="/user/CheckUserServlet2" name="">
    用户名字:<input type="text" name="username" id="uname">
    <input type="button" id="ver_btn" value="验证用户名" onclick="verifyUserName()">
    <!--        验证用户名的提示标签-->
    <span id="verificationUser" style="color: red"></span><br>
    用户密码:<input type="text" name="pwd" id="pwd"><br>
    电子邮件:<input type="text" name="email" id="email"><br>
    <input type="submit" value="用户注册" id="registerBtn"><br>
    <h1>返回的用户数据</h1>
    <div id="userData"></div>
</form>
</body>
</html>

3.在 register02.html 界面引入 JQUery 和 user2.js

注意:引入 JS 文件或者修改 JS 文件后,必须重新发布,

才会将文件构建到 out/target 目录,重新生效

//验证用户名是否存在
function verifyUserName() {
    $.ajax({
        url: "/user/CheckUserServlet", //请求的地址
        type: "GET",//请求的方式
        data: {
            username: $("#uname").val(),//请求/发送的数据
            data: new Date() //为了防止缓存
        },
        error: function () {//失败后的回调函数
            console.log("失败~");
        },
        success: function () {//成功后的回调函数
            console.log("成功~");
        },
        dataType: JSON //返回的数据类型:JSON
    });
}

4.在 Servlet 中接收发出的 AJAX 的数据,并模拟返回响应的数据

这里接收的数据的格式是根据 AJAX 的发出的格式规定的

设置返回的数据类型:JSON 类型

5.Ajax请求

注意:返回的 data 的属性与 JavaBean 的属性一致的

//验证用户名是否存在
function verifyUserName() {
    // 1.得到表单提交的数据
    //用户名
    // var uname = document.getElementById("uname").value;
    //验证是否得到表单数据
    // console.log("uname="+uname);
    //发出Ajax请求
    $.ajax({
        url: "/user/CheckUserServlet2", //请求的地址
        type: "POST",//请求的方式
        data: {
            username: $("#uname").val(),//请求/发送的数据
            data: new Date() //为了防止缓存
        },
        success: function (data, status, xhr) {//成功后的回调函数
            console.log("成功~");
            //请求成功后,返回data的数据
            console.log("data=", data);
            if ("" != data.uname) {
                $("#verificationUser").html("该用户已存在");
                $("#userData").text("用户名:" + data.uname);
            } else {
                $("#verificationUser").html("该用户不存在");
                $("#userData").text("");
            }
        },
        error: function (data, status, xhr) {//失败后的回调函数
            console.log("失败~");
            console.log("data=", data);
        },

        dataType: "json" //返回的数据类型:json
    });
}

 

6.get 请求

 $.get({
        url: "/user/CheckUserServlet2", //请求的地址
        data: {
            username: $("#uname").val(),//请求/发送的数据
            data: new Date() //为了防止缓存
        },
        success: function (data, status, xhr) {//成功后的回调函数
            console.log("成功~");
            //请求成功后,返回data的数据
            console.log("data=", data)
            if ("" != data.uname) {
                $("#verificationUser").html("该用户已存在");
                $("#userData").text("用户名:" + data.uname);
            } else {
                $("#verificationUser").html("该用户不存在");
                $("#userData").text("");
            }
        },
        error: function (data, status, xhr) {//失败后的回调函数
            console.log("失败~");
            console.log("data=", data)
        },

        dataType: "json" //返回的数据类型:json
    });

7.post 请求

语法和 get 请求一致

 $.post({
        url: "/user/CheckUserServlet2", //请求的地址
        data: {
            username: $("#uname").val(),//请求/发送的数据
            data: new Date() //为了防止缓存
        },
        success: function (data, status, xhr) {//成功后的回调函数
            console.log("成功~");
            //请求成功后,返回data的数据
            console.log("data=", data)
            if ("" != data.uname) {
                $("#verificationUser").html("该用户已存在");
                $("#userData").text("用户名:" + data.uname);
            } else {
                $("#verificationUser").html("该用户不存在");
                $("#userData").text("");
            }
        },
        error: function (data, status, xhr) {//失败后的回调函数
            console.log("失败~");
            console.log("data=", data)
        },

        dataType: "json" //返回的数据类型:json
    });

8.getJson 请求

请求的get方式,并且返回的数据类型是JSON格式的

参数1:url地址,参数2:请求的Data数据,参数3:成功后返回的data数据

//请求的get方式,并且返回的数据类型是JSON格式的
//参数1:url地址,参数2:请求的Data数据,参数3:成功后返回的data数据
    $.getJSON({
        url: "/user/CheckUserServlet2", //请求的地址
        data: {
            username: $("#uname").val(),//请求/发送的数据
            data: new Date() //为了防止缓存
        },
        success: function (data, status, xhr) {//成功后的回调函数
            console.log("成功~");
            //请求成功后,返回data的数据
            console.log("data=", data)
            if ("" != data.uname) {
                $("#verificationUser").html("该用户已存在");
                $("#userData").text("用户名:" + data.uname);
            } else {
                $("#verificationUser").html("该用户不存在");
                $("#userData").text("");
            }
        },
        // error: function (data, status, xhr) {//失败后的回调函数
        //     console.log("失败~");
        //     console.log("data=", data)
        // },
        // dataType: "json" //返回的数据类型:json
    });
  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
前后端交互实现登录和注册功能通常涉及以下几个步骤: 1. **前端提交表单**:用户在网页或移动应用填写用户名(通常是邮箱或手机号)和密码,然后点击登录或注册按钮。这些信息会被封装成JSON格式的数据,并通过HTTP请求发送到后端服务器。 2. **API调用**:前端使用Ajax、Fetch或axios等库向后端API发送POST请求,请求的数据包括用户输入的账号和密码(通常会对密码进行哈希加密后再传输,以保护安全)。 3. **后端验证**:后端服务器接收到请求后,检查数据的有效性和格式。这通常涉及到数据库查询,比如检查用户名是否存在,密码是否匹配数据库的记录。 4. **身份验证**:如果验证通过,后端会创建一个session token(有时也称为JWT)并返回给前端。这个token通常包含了用户的身份标识,前端将其存储起来(如cookies或localStorage),用于后续请求时验证身份。 5. **状态管理**:前端将token保存在客户端,每次发起需要权限控制的请求时,会在请求头添加该token。后端会验证这个token,判断用户是否已经登录。 6. **错误处理**:如果验证失败(如密码错误、账户不存在等),后端会返回错误信息给前端,前端展示给用户,并允许他们重新输入。 相关问题-- 1. 前端如何处理用户的登录请求? 2. 后端如何验证用户密码? 3. JWT在身份验证的作用是什么? 4. 如何防止前端直接暴露session token? 5. 注册时,如何保证用户信息的安全存储?
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值