Ajax(Asynchronous JavaScript And XML)异步的JavaScript和XML在不刷新页面的前提下进行页面的局部更新。用来同Servlet进行交互。
Ajax的处理流程
- 创建XMLHttpRequest对象
由于Ajax不是标准的W3C,所以对于不同版本的浏览器存在创建语法的差异,一般通过判断是否存在XmlHttpRequest对象来创建对象。
var xmlHttp;
if (window.XMLHttpRequest) {
// 适用于IE7+、Chrome、Firefox、Opera、Safari
xmlHttp = new XMLHttpRequest();
} else {
// 适用于IE6以下的版本
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
- 发送Ajax请求
创建请求:xmlHttp.open("GET | POST", "PathContent", true | false)
。调用open()方法创建请求,方法存在三个参数,第一个参数为请求方法,是使用GET或POST方法发送请求;第二个参数为请求的上下文路径;第三个参数为是否为异步请求。
异步与同步
在请求的过程中,若在还没返回响应时就可以继续进行后续代码的称为异步,相反的,若必须等待响应结果返回后才能继续执行的称为同步。简单的说,同步是需要等待的,而异步是不需要等待。所以一般情况下Ajax请求都是使用异步。
xmlHttp.open("GET", "/employee", true);
xmlHttp.send();
- 处理服务器响应
使用异步请求时需要调用onreadystatechange()
方法监听响Ajax的执行过程,可以调用XMLHttpServlet的readyState属性来查看当前状态。
readyState | 说明 |
---|---|
0 | 请求未初始化 |
1 | 服务器连接已建立 |
2 | 请求已被接收 |
3 | 请求正在处理 |
4 | 响应文本已被接收 |
一般通过readyState和status两个值来判断是否请求成功,status为Http响应结果。最后通过responseText()函数获取响应结果。
xmlHttp.onreadystatechange = funcation () {
if (xmlHttp.state == 4 && xmlHttp.status == 200) {
// 获取响应文本
var text = xmlHttp.responseText();
// 对响应文本进行逻辑处理
...
}
}
在Java的response响应时传递的为文本,所以Ajax和Java之间的交换一般使用JSON,将需要返回的JSON字符串作为参数返回前端,再在JavaScript中将JSON转换为数组。
示例:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>employee</title>
</head>
<body>
<input type="submit" value="加载" id="submit"/>
<div id="content"></div>
<script type="text/javascript">
document.getElementById("submit").onclick = function (ev) {
// 1.创建XMLHttpRequest
var xmlHttp;
if (window.XMLHttpRequest) {
xmlHttp = new XMLHttpRequest();
} else {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
// 2.创建并发送请求
xmlHttp.open("GET", "/Ajax/employee", true);
xmlHttp.send();
console.log("发送请求成功");
// 3.处理响应结果
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
// 获取响应文本
var text = xmlHttp.responseText;
// 将字符串转为JSON数组
var json = JSON.parse(text);
var html = "";
for (var i = 0; i < json.length; i++) {
var emp = json[i];
html += emp.empId + ":" + emp.name + "<br>";
}
console.log(json);
var content = document.getElementById("content").innerHTML = html;
}
}
}
</script>
</body>
</html>
package com.ajax;
import com.alibaba.fastjson.JSON;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@WebServlet("/employee")
public class EmployeeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
// 线程休眠5秒钟
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
List<Employee> list = new ArrayList<>();
Date date = new Date();
list.add(new Employee(9001, "Tom", 10000f, date, "B805"));
list.add(new Employee(9002, "Jack", 8000f, date, "B805"));
list.add(new Employee(9003, "Jerry", 3000f, date, "B805"));
String str = JSON.toJSONString(list);
System.out.println(str);
resp.getWriter().println(str);
}
}
由该例可以看出使用异步请求时,Servlet线程会休眠5秒才会执行,而前端会直接打印发送成功,在五秒后页面显示信息。如果使用同步时,此时不能再使用onreadystatechange()方法,需要把逻辑处理过程拿出来,可以发现需要等待5秒前端才会打印发送成功且显示页面信息。
JQuery对Ajax的支持
JQuery简化了JS的步骤对Ajax进行了封装,提供了$.ajax()方法。方法的参数为JSON对象,通过JSON对象来对参数进行描述。
常用设置项 | 说明 |
---|---|
url | 请求地址 |
type | 请求类型(GET | POST) |
data | 请求参数 |
dataType | 响应类型(text | json | xml | html | jsonp | script) |
success | 响应成功时的处理函数 |
error | 响应异常时的处理函数 |
对于data对应的值可使用attr=value&attr=value的格式设置参数,也可使用JSON对象来描述参数
对于success对应的函数会内置一个json参数获取响应返回的文本信息
对于error对应的函数会内置xmlhttp,errorText参数,获取服务器返回异常的XMLHttpServlet对象和异常内容
$.ajax({
"url":"/Ajax/employee",
"type":"GET",
"data":"name='Tom'",
"dataType":"json",
"success":function (json) {
console.log(json);
},
"error":function (xmlhttp, errorText) {
console.log(xmlhttp);
console.log(errorText);
}
})
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="./js/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
$(function () {
$.ajax({
"url":"/Ajax/employee",
"type":"GET",
"data":"name=张三",
"dataType":"json",
"success":function (json) {
console.log(json);
if (json != null)
$("#content").append("<p>" + json.name + "</p>");
else
$("#content").append("<p>未找到该人员</p>");
},
"error":function (xmlHttp, errorText) {
console.log(xmlHttp);
console.log(errorText);
}
});
});
</script>
</head>
<body>
<input type="submit" value="加载" id="submit"/>
<div id="content"></div>
</body>
</html>
package com.ajax;
import com.alibaba.fastjson.JSON;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@WebServlet("/employee")
public class EmployeeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
List<Employee> list = new ArrayList<>();
String name = req.getParameter("name");
System.out.println(name);
Date date = new Date();
list.add(new Employee(9001, "Tom", 10000f, date, "B805"));
list.add(new Employee(9002, "Jack", 8000f, date, "B805"));
list.add(new Employee(9003, "Jerry", 3000f, date, "B805"));
String str = null;
for (Employee e : list) {
if (e.getName().equals(name)) {
str = JSON.toJSONString(e);
System.out.println(str);
break;
}
}
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().println(str);
}
}