效果
前端
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
});