阶段性代码实操(2)- 项目前置准备
1.目标
通过完成一个较为综合的小小的案例,对所学的知识进行巩固与复习,期待温故而知新。
2.相关技术点
前端:巩固html,css,JavaScript,试着使用JavaScript的jQuery库简化代码
数据交换json与异步请求Ajax的使用
后端:tomcat,servlet,jdbc与数据库连接池,mysql
3.案例层次分析
4.走代码
4.1前端注册登录HTML界面
login.html文件
html实现主体结构内容(from表单提交+使用table进行表单格式化)
查看代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录界面</title>
<script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>
<script type="text/javascript" src="loginjs.js">
//这里写一个js文件,绑定事件,准备创建ajax引擎对象,发送请求给CheckUserServlet
</script>
</head>
<body>
<form action="/ajax/checkUserServlet" method="post">
<table border="0" width="600" align="center" cellspacing="15">
<tr align="center">
<th colspan="5"><h1>用户登录</h1></th>
</tr>
<tr>
<td >用户名:</td>
<td ><input type="text" name="username" id="uid"></td>
<td ><input type="button" value="验证用户名" id="checkBtn"><br/></td>
<td ><input type="text" id="noUser" style="color: salmon;border-width: 0"><br/></td>
</tr>
<tr>
<td>密 码:</td>
<td><input type="password" name="pwd"></td>
<td></td>
<td></td>
</tr>
<tr>
<td>邮 件:</td>
<td><input type="text" name="email"></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="登录" id="btn01">
<input type="reset" value="重新填写"></td>
<td></td>
<td></td>
</tr>
</table>
</form>
<h4 align="center">返回的json数据</h4>
<div align="center" id="div1">
</div>
</body>
</html>
中间部分html标签使用css格式进行表现外观改变
<td ><input type="text" id="noUser" style="color: salmon;border-width: 0"><br/></td>
使用Javascript用来实现网页上的行动的效果,采用引入js文件的方式
<script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>
<script type="text/javascript" src="loginjs.js">
//这里写一个js文件,绑定事件,准备创建ajax引擎对象,发送请求给CheckUserServlet
</script>
loginjs.js文件
// 在这里写js的逻辑
//顺带用用jQuery
$(function () {
var $btn01 = $("#checkBtn");
绑定onclick事件
$btn01.click(function () {
}
4.2 JS中Ajax使用
loginjs.js文件中使用Ajax实现异步请求与局部刷新
查看代码
// 在这里写js的逻辑
//顺带用用jQuery
$(function () {
var $btn01 = $("#checkBtn");
//2.绑定onclick事件
$btn01.click(function () {
//此处使用ajax进行异步交换数据:http请求-XmlHttpRequest
var xhr= new XMLHttpRequest();
//获取用户名:
//先绑定一个事件,先得到dom对象再绑定 ->简化:使用jQuery对象.val()
// document.getElementById("uid").value
var uname = $("#uid").val();
xhr.open("GET" ,"/ajax/checkUserServlet?username=" + uname,true);
//在send之前,给xhr对象绑定事件 onreadystatechange()
//事件表示可以指定一个函数,当数据变化时触发
xhr.onreadystatechange=function (){
// raedyState:2请求已接收,4请求已完成,且响应已就绪
if(xhr.readyState == 4 && xhr.status==200){
console.log("xhr = ", xhr);
//挑选其中的respText
var responseText = xhr.responseText;
//返回json数据到div,这里text也可以
$("#div1").html(responseText);
console.log(responseText);
if (responseText!=""){
$("#noUser").val("该用户名不可用!");
}else{
$("#noUser").val("用户名可用");
}
}
}
xhr.send();
})
})
4.3Servlet层
servlet接收到html的from表单提交的数据,然后提供Service层提供的对象以及具体的业务方法从数据库获取信息,返回响应
查看代码
public class CheckUserServlet extends javax.servlet.http.HttpServlet {
//CheckUserServlet要调UserService对象的方法,所以给它设置一个属性对象
private UserService userService = new UserService();
protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
String uname = request.getParameter("username");
System.out.println(uname);
//user中有中文
response.setContentType("text/html;charset=utf-8");
// if ("king".equals(uname)){
// //之后使用DB+jdbc获取
// User king = new User(100, "king", "123456", "king@qq.com");
// PrintWriter writer = response.getWriter();
// //把king转成json字符串
// writer.print(new Gson().toJson(king));
// }else {
// response.getWriter().write("");
// }
//使用数据库获取信息
User userByName = userService.getUserByName(uname);
if (userByName!=null){
response.getWriter().write(new Gson().toJson(userByName));
}else{
response.getWriter().write("");
}
}
protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
doPost(request,response);
}
}
4.4Service层
service层中设置一个私有的dao对象,用来通过这个对象调用dao层提供的(用来拿数据的,操作数据库的)的方法。
然后将上述行为封装成方法供servlet层使用。
4.5DAO层
1.开发BasicDAO , 是其他DAO的父类 封装通用的dml方法, 针对任意的表;封装返回不同查询结果的dql方法
查看代码
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);
}
}
}
2.对应表的dao继承basicdao,使用方法
public class UserDao extends BasicDAO <User>{
//继承basicdao并将泛型指定为User,将来返回的类型就是User
}
4.6entity层
映射db中的表,方便其他层使用对象来对应一行表的数据
//javabean,pojo,domin,entity
//javabean 中的字段要和数据库表的字段一一对应
查看代码
public class User {
//javabean,pojo,domin,entity
//javabean 中的字段要和数据库表的字段一一对应,一定要一致!
private Integer id;
private String username;
private String password;
private String email;
public User() {
}
//此处需要提供一个无参构造器,供我们底层反射使用;
public User(Integer id, String username, String password, String email) {
this.id = id;
this.username = username;
this.password = password;
this.email = email;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
4.7数据库
建库,建表
查看代码
CREATE DATABASE ajaxdb
CHARACTER SET utf8
COLLATE utf8_bin
CREATE TABLE `user`(
id INT PRIMARY KEY,
username VARCHAR(32) NOT NULL DEFAULT '',
`password` CHAR(32) NOT NULL DEFAULT '',
email VARCHAR(32)NOT NULL DEFAULT ''
) CHARSET utf8 ENGINE INNODB
INSERT INTO `user` VALUES(10,'king',MD5('123'),'king@qq.com');
INSERT INTO `user` VALUES(20,'monkey',MD5('666'),'monkey@qq.com');
INSERT INTO `user` VALUES(30,'cat',MD5('888'),'cat@qq.com');
SELECT * FROM `user`