文章目录
1.案例需求
使用父子模块的maven以及Ajax实现人工管理系统的增删改查,具体的运行效果如下图。
工程视图如下:
2.编程思路
- 登录功能:
- 前端处理
- 用户名存在性检查:当用户在用户名输入框(#username)中失去焦点(blur事件)时,通过AJAX向服务器发送请求,检查该用户名是否已存在。请求中包含用户名(username)和一个指示操作的方法名(method: "isExists")。服务器端响应后,根据返回的JSON数据(data),更新页面上的消息提示(#msg)。
- 提交表单:用户点击提交按钮(#sub)时,阻止表单的默认提交行为(event.preventDefault()),转而使用AJAX发送登录请求。请求中包含用户名(username)、密码(password)和指示操作的方法名(method: "login")。根据服务器返回的JSON数据,更新页面上的消息提示(#mess),并根据登录结果(成功或失败)跳转到相应的页面。
后端处理
- 用户登录处理(doLogin 方法):接收前端发送的用户名(username)和密码(password),调用业务逻辑层(empService.queryEmp)进行用户认证,通常是通过查询数据库中的用户名和密码是否匹配, 根据查询结果(result),构造JSON格式的响应数据,并通过PrintWriter输出到HTTP响应体中,如果用户名和密码匹配(result == 0),则登录成功,返回状态码200和成功消息,如果不匹配,则返回状态码100和错误消息。
- 用户名存在性检查(isExists 方法:接收前端发送的用户名(username),调用业务逻辑层(empService.queryEmpByName)查询该用户名是否存在,根据查询结果(emp),构造JSON格式的响应数据,并通过PrintWriter输出到HTTP响应体中, 如果用户不存在(emp == null),则返回状态码200和不存在用户的消息,如果用户存在,则返回状态码100和用户名存在的消息。
- 前端处理
- 新增功能:
- 前端处理
- 用户名失焦检查:当用户在用户名输入框(#empname)中完成输入并失去焦点时,通过AJAX向服务器发送请求,检查该用户名是否已存在。这是为了防止用户注册时使用已存在的用户名。
- 部门编号下拉列表填充:通过AJAX从服务器获取部门信息,并动态填充到部门编号的下拉列表(#empdeptno)中。这提高了用户界面的友好性和数据的准确性。
- 新增按钮点击事件:用户填写完注册信息后,点击新增按钮(#subbuton),通过AJAX向服务器发送注册请求。这里阻止了表单的默认提交行为,使用AJAX进行异步处理。
- 后端处理
- 用户名存在性检查(isExistsRegister 方法):接收前端发送的用户名,调用业务逻辑层(empService.queryEmpByName)查询该用户名是否已存在。根据查询结果构造JSON响应,返回给前端。
- 新增用户处理(doRegister 方法):接收前端发送的注册信息,构造Emp对象,并调用业务逻辑层(empService.addEmp)进行用户新增操作。根据操作结果构造JSON响应,返回给前端。
- 前端处理
- 查询功能:
- 前端思路
- 发送AJAX请求:在页面的JavaScript代码中,使用$.ajax方法向后端发送GET请求,请求URL为loginServlet(这里可能是示例代码,实际中应该是处理员工数据查询的Servlet URL)。
- 处理响应数据:在AJAX请求的success回调函数中,处理从后端返回的JSON数据。通常,这些数据是一个数组,每个元素都是一个包含员工信息的对象。
- 动态构建表格:遍历这个数组,为每个员工对象创建一个表格行(),并为每个属性(如员工编号、姓名、职位等)创建一个表格单元格()。同时,可以为每行添加操作按钮(如修改、删除),并为这些按钮设置事件监听器。
- 更新DOM:将构建好的表格行添加到页面的表格体()中,更新DOM以显示最新的员工信息。
- 事件监听与处理:为操作按钮(如修改、删除按钮)设置事件监听器,以便在用户点击时执行相应的操作(如弹出编辑对话框、发送删除请求等)。
- 后端编程思路
- 设置响应类型:在Servlet中,首先需要设置响应的内容类型为application/json;charset=utf-8,这是为了告诉浏览器这个响应是一个JSON格式的数据,且字符编码为UTF-8。
- 接收请求参数:根据需求,可能需要从HTTP请求中获取一些查询参数(如部门名dname、职位job、薪水sal等),以便进行条件查询。
- 构建查询条件:将接收到的参数封装成一个查询对象(如EmpVo),这个对象包含了所有可能的查询条件。
- 执行查询:调用服务层(如empAndDeptService.queryAllEmps(empVo))执行查询,返回所有符合条件的员工及其部门信息(这里假设是EmpAndDept对象的列表)。
- 序列化为JSON:使用Jackson或类似的库将Java对象列表(List)序列化为JSON格式的字符串,并将这个字符串写入到HTTP响应的输出流中。
- 返回响应:发送HTTP响应给前端,前端将使用这个JSON数据来更新页面内容。
- 前端思路
- 修改功能:
- 前端部分
- 初始化页面:使用jQuery的$(function() {...})来确保DOM元素加载完成后执行函数。从localStorage中获取员工编号(empno),用于查询员工信息。通过AJAX向服务器发送请求,获取指定员工的信息,并填充到表单中。
- 处理表单提交:为更新按钮(#updatesub)绑定点击事件,阻止表单的默认提交行为。收集表单中的员工信息,包括ID、姓名、职位、上级ID、入职时间、薪资、奖金、部门编号等。通过AJAX再次向服务器发送请求,包含员工的更新信息。根据服务器的响应,显示更新结果,并跳转到相应的页面。
- 后端部分
- 设置响应内容类型:设置响应的Content-Type为application/json;charset=utf-8,确保返回的数据是JSON格式,并且字符集为UTF-8。
- 接收请求参数:通过HttpServletRequest对象获取前端发送过来的所有请求参数,包括员工的各个字段信息。
- 参数处理:对获取到的参数进行必要的类型转换,如将字符串转换为Integer或Double等。
特别注意处理日期字符串,使用SimpleDateFormat将字符串转换为Date对象。 - 业务逻辑处理:创建一个Emp对象,并将转换后的参数设置到这个对象中。调用业务层(empService)的updateEmp方法来更新员工信息。
- 返回结果:根据业务层返回的更新结果(成功或失败),构造JSON格式的响应字符串。使用PrintWriter将JSON字符串写入到响应体中,以便前端进行解析和处理。
- 前端部分
- 删除功能
- 前端部分
- 事件绑定:假设 delRow() 函数是通过某个按钮(比如删除按钮)的点击事件触发的。这个函数将当前触发事件的元素(this)的 id 保存到本地存储(localStorage)中。这里 id 很可能指的是要删除的员工编号(empno)。
- 发送 AJAX 请求:使用 jQuery 的 $.ajax 方法发送一个 POST 请求到服务器端的 loginServlet(尽管命名上可能有些误导,因为它实际上处理的是删除操作)。
请求中包含了两个参数:empno(从本地存储中获取的员工编号)和 method(指示这是一个删除操作)。 - 处理响应:服务器响应后,根据返回的数据(JSON 格式),前端会更新页面。如果返回的状态码(data.code)是 200,表示删除成功,前端会清空表格体(#myTbody),并根据返回的员工列表(data.emps)重新渲染表格。如果删除失败,前端只是显示错误信息,不会清空或重新渲染表格。
- 后端部分
- 处理请求:服务器端接收到 AJAX 请求后,通过 request.getParameter 方法获取请求参数(如 empno)。根据员工编号(empno)调用 empService.deleteEmpById 方法执行删除操作,并获取操作结果。
- 查询并返回数据:服务器端还可能需要根据请求中的其他参数(如 searchdname、searchjob、searchsal)来过滤查询结果。这些参数可能用于在用户执行删除操作后,根据用户的搜索条件重新加载表格数据。使用这些参数构建查询条件,调用empAndDeptService.queryAllEmps方法查询员工信息。
- 构建响应:根据删除操作的结果和查询到的员工信息,构建一个响应对象(responseMap),其中包含状态码(code)、消息(message)和员工列表(emps)。使用 objectMapper.writeValue 方法将响应对象转换为 JSON 字符串,并写入到 HTTP 响应中,以便前端解析和显示。
- 前端部分
3.案例核心源码
登录功能的ajax核心代码:
java
<!-- 判断用户名是否存在-->
$(function () {
$("#username").blur(function () {
$.ajax({
url: "loginServlet",//发送请求到loginServlet
type: "post",
data: {
username: $("#username").val(),
method: "isExists"
},
success: function (data) {
$("#msg").html(data.message);
dataType: "json"
});
});
});
// 提交按钮的点击事件
$(function () {
$("#sub").click(function (event) {
event.preventDefault();
$.ajax({
url: "loginServlet",
type: "post",
data: {
username: $("#username").val(),
password: $("#pass").val(),
method: "login"
},
success: function (data) {
$("#mess").html(data.message);
if (data.code == 200) {//登录成功
window.location.href = "http://localhost:8080/MavenEmpManager_web/showAllEmps.html";
} else {
window.location.href = "http://localhost:8080/MavenEmpManager_web/login.html";
}
},
dataType: "json"
});
});
});
登录功能的servlet核心代码:
java
private void doLogin(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("application/json;charset=utf-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
int result = empService.queryEmp(username, password);
PrintWriter out = response.getWriter();
String json = "";
if (result == 0) {
json = "{\"code\":200, \"message\":\"登录成功\"}";
} else {
json = "{\"code\":100, \"message\":\"密码错误登录失败\"}";
}
out.write(json);
out.close();
}
private void isExists(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("application/json;charset=utf-8");
String username = request.getParameter("username");
Emp emp = empService.queryEmpByName(username);
PrintWriter out = response.getWriter();
String json = "";
if (emp == null) {
json = "{\"code\":200,\"message\":\"不存在该用户,请重新输入\"}";
} else {
json = "{\"code\":100,\"message\":\"该用户名存在,请登录\"}";
}
out.write(json);
out.close();
}
新增功能的ajax核心代码:
java
<!--用户名是否存在的失焦事件-->
$(function () {
$("#empname").blur(function () {
$.ajax({
url: "loginServlet",
type: "post",
data: {
username: $("#empname").val(),
method: "isExistsRegister"
},
success: function (data) {
$("#msg").html(data.message);
},
dataType: "json"
});
});
});
/*设置部门编号中select里面的option*/
$(function () {
//获取id为empdeptno的元素
var objselect = document.getElementById("empdeptno");
$.ajax({
url: "loginServlet",
type: "post",
data:{
method:"select"
},
success: function (data) {
for (var i = 0; i < data.length; i++) {
var deptjson = data[i];
//text,value
objselect.add(new Option(deptjson.dname, deptjson.deptno));
}
},
dataType:"json"
});
});
// 新增按钮的点击事件
$(function () {
$("#subbuton").click(function (event) {
event.preventDefault();//阻止表单的默认提交行为
$.ajax({
url: "loginServlet",
type: "post",
data: {//发送到服务器的数据
empid: $("#empid").val(),
empname: $("#empname").val(),
empjob: $("#empjob").val(),
empmgr: $("#empmgr").val(),
emptime: $("#emptime").val(),
empsal: $("#empsal").val(),
empcomm: $("#empcomm").val(),
empdeptno: $("#empdeptno").val(),
emppass: $("#emppass").val(),
method: "register"
},
success: function (data) {
$("#mess").html(data.message);
if (data.code == 200) {
window.location.href = "http://localhost:8080/MavenEmpManager_web/showAllEmps.html";
}else {
window.location.href = "http://localhost:8080/MavenEmpManager_web/register.html";
}
},
dataType: "json"
});
});
});
新增功能的servlet核心代码:
java
private void doRegister(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("application/json;charset=utf-8");
Integer empid = Integer.valueOf(request.getParameter("empid"));
String empname = request.getParameter("empname");
String empjob = request.getParameter("empjob");
Integer empmgr = Integer.valueOf(request.getParameter("empmgr"));
String time = request.getParameter("emptime");
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date emptime = null;
try {
emptime = dateFormat.parse(time);
} catch (ParseException e) {
throw new RuntimeException(e);
}
Double empsal = Double.valueOf(request.getParameter("empsal"));
Double empcomm = Double.valueOf(request.getParameter("empcomm"));
Integer empdeptno = Integer.valueOf(request.getParameter("empdeptno"));
String emppass = request.getParameter("emppass");
Emp emp = new Emp(empid, empname, empjob, empmgr, emptime, empsal, empcomm, empdeptno, emppass);
int result = empService.addEmp(emp);
PrintWriter out = response.getWriter();
String json = "";
if (result == 1) {
json = "{\"code\":200, \"message\":\"新增成功\"}";
} else {
json = "{\"code\":100, \"message\":\"新增失败\"}";
}
out.write(json);
out.close();
}
private void isExistsRegister(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("application/json;charset=utf-8");
String username = request.getParameter("username");
Emp emp = empService.queryEmpByName(username);
PrintWriter out = response.getWriter();
String json = "";
if (emp == null) {
json = "{\"code\":200,\"message\":\"不存在该用户,可以注册\"}";
} else {
json = "{\"code\":100,\"message\":\"该用户名存在,请重新输入\"}";
}
out.write(json);
out.close();
}
查询功能的ajax核心代码
java
$(function () {
$.ajax({
url: "loginServlet",
type: "get",
success: function (data) {
for (var i = 0; i < data.length; i++) {
var empjson = data[i];
addRow(empjson);
}
},
dataType: "json"
});
});
function addRow(empjson) {
var myTbody = document.getElementById("myTbody");
var row = document.createElement("tr");
var td1 = document.createElement("td");
td1.innerText = empjson.empno;
var td2 = document.createElement("td");
td2.innerText = empjson.ename;
var td3 = document.createElement("td");
td3.innerText = empjson.job;
var td4 = document.createElement("td");
td4.innerText = empjson.mgr;
var td5 = document.createElement("td");
td5.innerText = empjson.hiredate;
var td6 = document.createElement("td");
td6.innerText = empjson.sal;
var td7 = document.createElement("td");
td7.innerText = empjson.comm;
var td8 = document.createElement("td");
td8.innerText = empjson.deptno;
var td9 = document.createElement("td");
td9.innerText = empjson.dname;
var td10 = document.createElement("td");
var updatebtn = document.createElement("input");
updatebtn.type = "button";
updatebtn.value = "修改";
updatebtn.id = empjson.empno;
updatebtn.onclick = editRow;
var deletebtn = document.createElement("input");
deletebtn.type = "button";
deletebtn.value = "删除";
deletebtn.id = empjson.empno;
deletebtn.onclick = delRow;
td10.appendChild(updatebtn);
td10.appendChild(deletebtn);
row.appendChild(td1);
row.appendChild(td2);
row.appendChild(td3);
row.appendChild(td4);
row.appendChild(td5);
row.appendChild(td6);
row.appendChild(td7);
row.appendChild(td8);
row.appendChild(td9);
row.appendChild(td10);
myTbody.appendChild(row);
查询功能的servlet核心代码:
java
private void showEmps(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("application/json;charset=utf-8");
request.setCharacterEncoding("utf-8");
String dname = request.getParameter("searchdname");
String job = request.getParameter("searchjob");
String sal = request.getParameter("searchsal");
double empsal = 0;
if (sal != null && !sal.trim().isEmpty()) {
empsal = Double.parseDouble(sal.trim());
}
EmpVo empVo = new EmpVo(dname, job, empsal);
List<EmpAndDept> emps = empAndDeptService.queryAllEmps(empVo);
// List<Emp> emps = empService.queryAllEmps();
// System.out.println(emps);
//将Java对象emps序列化为JSON格式
objectMapper.writeValue(response.getWriter(), emps);
}
private void doSelect(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("application/json;charset=utf-8");
List<Dept> depts = deptService.queryAllDept();
//将Java对象depts序列化为JSON格式,并将这个JSON字符串写入到一个HTTP响应中
objectMapper.writeValue(response.getWriter(), depts);
}
修改的ajax核心代码:
java
function editRow() {
//将id在本地存储 this:当前按钮对象
localStorage.setItem("empno", this.id);
//打开修改页面
window.location.href = "updateEmp.html";
}
/*将指定id员工的信息显示出来*/
$(function () {
var eno = localStorage.getItem("empno");
// var objselect = document.getElementById("");
$.ajax({
url: "loginServlet",
type: "post",
data: {
empno: eno,
method: "queryByEmpno"
},
success: function (data) {
if (data.code == 200) {
$('#empid').val(data.emp.empno);
$('#empname').val(data.emp.ename);
var selectElement = document.getElementById('empjob');
var options = selectElement.getElementsByTagName('option');
for (var i = 0; i < options.length; i++) {
var value = options[i].value;
if (value == data.emp.job) {
options[i].selected = true;
break;
}
}
$('#empmgr').val(data.emp.mgr);
$('#emptime').val(data.emp.hiredate);
$('#empsal').val(data.emp.sal);
$('#empcomm').val(data.emp.comm);
var seElement = document.getElementById('empdeptno');
for (var i = 0; i < data.depts.length; i++) {
var deptjson = data.depts[i];
seElement.add(new Option(deptjson.dname, deptjson.deptno));
}
var os = seElement.getElementsByTagName('option');
for (var i = 0; i < os.length; i++) {
var value = os[i].value;
if (value == data.emp.deptno) {
os[i].selected = true;
break;
}
}
// $('#empdeptno').val(data.emp.deptno);
$('#emppass').val(data.emp.password);
}
},
dataType: "json"
});
});
$(function () {
$("#updatesub").click(function (event) {
event.preventDefault();
$.ajax({
url: "loginServlet",
type: "post",
data: {
empid: $("#empid").val(),
empname: $("#empname").val(),
empjob: $("#empjob").val(),
empmgr: $("#empmgr").val(),
emptime: $("#emptime").val(),
empsal: $("#empsal").val(),
empcomm: $("#empcomm").val(),
empdeptno: $("#empdeptno").val(),
method: "update"
},
success: function (data) {
$("#str2").html(data.message);
if (data.code == 200) {
window.location.href = "http://localhost:8080/MavenEmpManager_web/showAllEmps.html";
} else {
window.location.href = "http://localhost:8080/MavenEmpManager_web/updateEmp.html";
}
},
dataType: "json"
});
});
});
修改功能的servlet核心代码:
java
private void doUpdate(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("application/json;charset=utf-8");
// request.setCharacterEncoding("utf-8");
Integer empid = Integer.valueOf(request.getParameter("empid"));
String empname = request.getParameter("empname");
String empjob = request.getParameter("empjob");
Integer empmgr = Integer.valueOf(request.getParameter("empmgr"));
String time = request.getParameter("emptime");
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date emptime = null;
try {
emptime = dateFormat.parse(time);
} catch (ParseException e) {
throw new RuntimeException(e);
}
Double empsal = Double.valueOf(request.getParameter("empsal"));
Double empcomm = Double.valueOf(request.getParameter("empcomm"));
Integer empdeptno = Integer.valueOf(request.getParameter("empdeptno"));
Emp emp = new Emp(empid, empname, empjob, empmgr, emptime, empsal, empcomm, empdeptno);
int result = empService.updateEmp(emp);
PrintWriter out = response.getWriter();
String json = "";
if (result == 1) {
json = "{\"code\":200, \"message\":\"修改成功\"}";
} else {
json = "{\"code\":100, \"message\":\"修改失败\"}";
}
out.write(json);
out.close();
}
删除功能的ajax核心代码:
java
function delRow() {
//将id在本地存储 this:当前按钮对象
localStorage.setItem("empno", this.id);
var empno = localStorage.getItem("empno");
$(function () {
$.ajax({
url: "loginServlet",
type: "post",
data: {
empno: empno,
method: "delete"
},
success: function (data) {
$("#str").html(data.message);
if (data.code == 200) {
$("#myTbody").empty();
for (var i = 0; i < data.emps.length; i++) {
var empjson = data.emps[i];
addRow(empjson);
}
}
},
dataType: "json"
});
});
}
删除功能的servlet核心代码:
java
private void doDeleteEmp(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("application/json;charset=utf-8");
String empno = request.getParameter("empno");
int result = empService.deleteEmpById(empno);
String dname = request.getParameter("searchdname");
String job = request.getParameter("searchjob");
String sal = request.getParameter("searchsal");
double empsal = 0;
if (sal != null && !sal.trim().isEmpty()) {
empsal = Double.parseDouble(sal.trim());
}
EmpVo empVo = new EmpVo(dname, job, empsal);
List<EmpAndDept> emps = empAndDeptService.queryAllEmps(empVo);
Map<String, Object> responseMap = new HashMap<>();
if (result > 0) {
responseMap.put("code", 200);
responseMap.put("message", "删除成功!");
responseMap.put("emps", emps);
} else {
responseMap.put("code", 100);
responseMap.put("message", "删除失败!");
}
objectMapper.writeValue(response.getWriter(), responseMap);
}
4.小结
Ajax是一种用于创建交互式网页应用的网页开发技术,它允许网页在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页内容。以下是Ajax技术的几个关键点总结:
- 基本概念
异步请求:Ajax的核心特性是异步通信。与同步请求不同,异步请求允许浏览器在等待服务器响应时继续执行其他操作,从而提高了用户体验。
XMLHttpRequest对象:Ajax技术通过XMLHttpRequest对象与服务器进行通信。这个对象提供了向服务器发送请求并接收响应的功能。 - 工作原理
Ajax通过JavaScript创建XMLHttpRequest对象。
使用XMLHttpRequest对象的open()方法配置请求,包括请求方法(GET或POST)、URL地址以及是否异步处理。
通过send()方法发送请求到服务器。
浏览器在等待服务器响应时,可以继续执行其他操作。
当服务器响应就绪时,XMLHttpRequest对象的onreadystatechange事件会被触发,此时可以读取响应数据并更新页面内容。 - 关键技术
JavaScript:用于操作DOM,实现页面的动态更新。
XMLHttpRequest:用于在后台与服务器交换数据。
CSS:用于控制页面的样式和布局。
DOM(文档对象模型):提供了访问和操作网页内容的方法和接口。 - 请求与响应
请求:Ajax请求可以包含多种信息,如请求方法(GET或POST)、URL地址、请求头、请求体等。
响应:服务器响应通常包括状态码、响应头和响应体。状态码用于指示请求是否成功,响应体包含实际的数据内容。 - 优点与缺点
- 优点:
无需重新加载整个页面,提高了用户体验。
可以与服务器进行异步通信,提高了应用的响应速度。
可以实现丰富的交互效果,如实时数据更新、表单验证等。 - 缺点:
安全性问题:Ajax请求可能会被拦截或篡改。
对搜索引擎不友好:由于Ajax技术更新的是页面的部分内容,搜索引擎可能无法完全抓取到这些更新的内容。
跨域问题:Ajax请求受到同源策略的限制,不能跨域发送请求(但可以通过CORS等技术解决)。