传统的页面交互是Servlet 调用完业务逻辑层后将数据存储到域对象中,然后跳转到指定的 jsp 页面,在页面上使用 EL表达式 和JSTL 标签库进行数据的展示。该模式存在以下问题:
所有现代浏览器(IE7+、Firefox、Chrome、Safari 以及 Opera)均内建 XMLHttpRequest 对象。
XMLHttpRequest 用于在后台与服务器交换数据。它可以在不向服务器提交整个页面的情况下,实现局部更新网页。
XMLHttpRequest的对象用于客户端和服务器之间的异步通信。
它执行以下操作:
var http=new XMLHttpRequest();
XMLHttpRequest对象的常见属性如下:
| 属性 | 描述 |
|---|---|
| onreadystatechange | 存储函数(或函数名),每当readyState的属性改变时,就会调用该函数。 |
| readyState | 存有的XMLHttpRequest的状态从0到4发生变化。 0:请求未初始化 1:服务器连接已建立 2:请求已接收 3:请求处理中 4:请求已完成,且响应已就绪 |
| responseText | 以文本形式返回响应。 |
| responseXML | 以XML格式返回响应 |
| status | 将状态返回为数字(例如,“Not Found”为404,“OK”为200) |
| statusText | 以字符串形式返回状态(例如,“Not Found”或“OK”) |
XMLHttpRequest对象的重要方法如下:
| 方法 | 描述 |
|---|---|
| abort() | 取消当前请求。 |
| getAllResponseHeaders() | 以字符串形式返回完整的HTTP标头集。 |
| getResponseHeader( headerName ) | 返回指定HTTP标头的值。 |
| void open(method,URL) | 打开指定获取或交的方法和URL的请求。 |
| void open(method,URL,async) | 与上面相同,但指定异步或不。 |
| void open(method,URL,async,userName,password) | 与上面相同,但指定用户名和密码。 |
| void send(content) | 发送获取请求。 |
| setRequestHeader( label,value) | 将标签/值对添加到要发送的HTTP标头。 |
AJAX 使用的 XMLHttpRequest 的对象与服务器通信, AJAX 的工作原理如图:

ajax请求流程如下:
当你的页面全部加载完毕后,客户端会通过 XMLHttpRequest 对象向服务器请求数据,服务器端接受数据并处理后,向客户端反馈数据。如需将请求发送到服务器,我们使用 XMLHttpRequest 对象的open()和send()方法:
//创建Ajax对象
var http=new XMLHttpRequest();
//设置Ajax的请求地址与请求方式
http.open("get","http://localhost:8080/GetUserInfoServlet");
//发送请求
http.send();
由于 HTTP 响应是由服务端发出的,并且服务器做出响应需要时间(比如网速慢等原因),所以需要监听服务器响应的状态,然后才能进行处理。
| 属性 | 描述 |
|---|---|
| responseText | 获得字符串形式的响应数据。 |
| responseXML | 获得 XML 形式的响应数据。 |
当发送一个请求后,客户端需要确定这个请求什么时候会完成,因此,XMLHttpRequest对象提供了onreadystatechange事件机制来捕获请求的状态,继而实现响应。
当请求被发送到服务器时,执行一些基于响应的任务,每当readyState改变时,就会触发onreadystatechange事件。readyState属性存有 XMLHttpRequest 的状态信息。
| 属性 | 描述 |
|---|---|
onreadystatechange | 存储函数(或函数名),每当readyState属性改变时,就会调用该函数。 |
readyState | 存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。
|
status | 200: "OK" 404: 未找到页面 |
回调函数事件
http.onreadystatechange=function () {
//readyState 0=>初始化 1=>载入 2=>载入完成 3=>解析 4=>完成
if(this.readyState==4&&this.status==200){
var responseText=this.responseText
console.log('返回结果:'+responseText)
}
}
(1)GetUserInfoServlet接口
@WebServlet("/GetUserInfoServlet")
public class GetUserInfoServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
String username=req.getParameter("username");
String password=req.getParameter("password");
User user = new User();
user.setUsername(username);
user.setPassword(password);
String content= JSON.toJSONString(user);
PrintWriter writer = resp.getWriter();
writer.write(content);
}
}
(2)ajax页面请求
function getUserInfo() {
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
//创建Ajax对象
var http=new XMLHttpRequest();
//设置Ajax的请求地址与请求方式
var params='username='+username+'&password='+password;
http.open("get","http://localhost:8080/GetUserInfoServlet?"+params);
//发送请求
http.send();
//获取响应数据
http.onreadystatechange=function () {
//readyState 0=>初始化 1=>载入 2=>载入完成 3=>解析 4=>完成
if(this.readyState==4&&this.status==200){
var responseText=this.responseText
console.log('返回结果:'+responseText)
var result=JSON.parse(responseText);
console.log('解析结果:password:'+result.password+' username:'+result.username)
}
}
}
(1)GetUserInfoServlet接口
@WebServlet("/UserLoginServlet")
public class UserLoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
//解析参数
InputStreamReader insr = new InputStreamReader(req.getInputStream(),"utf-8");
String res = "";
int respInt = insr.read();
while(respInt!=-1) {
res +=(char)respInt;
respInt = insr.read();
}
User user=JSON.parseObject(res,User.class);
//返回结果
Result result = new Result();
if(user.getUsername()==null||user.getUsername().isEmpty()){
result.setSuccess(false);
result.setErrorCode(-1);
result.setErrorMsg("请输入用户名");
}else if(user.getPassword()==null||user.getPassword().isEmpty()){
result.setSuccess(false);
result.setErrorCode(-1);
result.setErrorMsg("请输入密码");
}else if(!user.getUsername().equals("admin")||!user.getPassword().equals("admin")){
result.setSuccess(false);
result.setErrorCode(-1);
result.setErrorMsg("用户名或者密码错误");
}else {
result.setSuccess(true);
}
PrintWriter writer = resp.getWriter();
writer.write(JSON.toJSONString(result));
}
}
(2)ajax页面请求
function login() {
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
//创建Ajax对象
var http=new XMLHttpRequest();
//设置Ajax的请求地址与请求方式
http.open("post","http://localhost:8080/UserLoginServlet");
//设置请求的参数格式的类型(post请求必须要设置)
// http.setRequestHeader('Content-type','application/x-www-form-urlencoded') username=123&password=344
http.setRequestHeader('Content-type','application/json')
//发送请求
http.send(JSON.stringify({
username:username,
password:password
}));
//获取响应数据
http.onreadystatechange=function () {
//readyState 0=>初始化 1=>载入 2=>载入完成 3=>解析 4=>完成
if(this.readyState==4&&this.status==200){
var responseText=this.responseText
console.log('返回结果:'+responseText)
var result=JSON.parse(responseText);
if(result.success){
alert('登录成功')
}else {
alert(result.errorMsg)
}
}
}
}