ajax是什么?
asynchronous javascript and xml(异步的javascript和xml),其实质可以理解 为:
使用浏览器内置的一个对象(XmlHttpRequest)向服务器发送请求,
服务器返回xml数据或者是文本数据给浏览器,
然后在浏览器端,使用这些数据更新部分页面,整个过程,页面无任何的刷新。
这里我们以上一篇中的登录为例,不采用表单提交方式,而是用ajax请求。
一,更改login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="./js/login.js"></script>
</head>
<body>
<label>用户名</label>
<input type="text" id="name" name="name" />
<br/>
<label>密码</label>
<input type="text" id="password" name="password" />
<br/><br/>
<button οnclick="login()">登录</button>
<span id="msg"></span>
</body>
</html>
二,在webapp目录下新建js/login.js
function login() {
var name = document.getElementById('name').value;
var password = document.getElementById('password').value;
// 获取XmlHttpRequest对象
var xhr = getXmlHttpRequest();
xhr.open('post', '/webDemo/send_ajax', false);
// 必须添加一个消息头content-type
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.onreadystatechange=function(){
//编写相应的处理代码
if(xhr.readyState == 4){
//只有readyState等亍4,xhr才完整地接收到了服务器返回的数据。
if (xhr.status == 200) {
//获得文本数据
var txt = xhr.responseText;
//dom操作、更新页面
document.getElementById('msg').innerHTML=txt;
} else {
document.getElementById('msg').innerHTML="系统错误";
}
}
};
xhr.send('name='+name+'&password='+password);
}
function getXmlHttpRequest() {
var xhr = null;
if ((typeof XMLHttpRequest) != 'undefined') {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject('Microsoft.XMLHttp');
}
return xhr;
}
三,新建AjaxServlet
package com.example.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class AjaxServlet extends HttpServlet {
private static final long serialVersionUID = 6364639862439643474L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
super.doGet(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求参数编码
req.setCharacterEncoding("utf-8");
//设置响应格式
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
String name = req.getParameter("name");
String password = req.getParameter("password");
//获取输出流
PrintWriter out = resp.getWriter();
if (name.equals("李四") && password.equals("123")) {
out.println("登录成功");
} else {
out.println("用户名或密码错误");
}
out.flush();
out.close();
}
}
四,在web.xml中配置映射
<servlet>
<servlet-name>AjaxServlet</servlet-name>
<servlet-class>com.example.servlet.AjaxServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AjaxServlet</servlet-name>
<url-pattern>/send_ajax</url-pattern>
</servlet-mapping>
五,启动测试:http://localhost:8088/webDemo/login.html
返回结果:
可以看到,页面没有刷新,返回数据成功。
这里返回的是text文本信息,那么我们如何从后台获取到需要的数据显示到页面呢?
这里我们就需要用到Json字符串格式来传递数据了。
六,引入jackson的依赖包:
<!-- jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.6.5</version>
</dependency>
七,在login.html中添加一个查询按钮:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="./js/login.js"></script>
</head>
<body>
<!-- 表单提交 -->
<!-- <form id="form" action="/webDemo/login.do" method="post">
<label>用户名</label>
<input type="text" id="name" name="name" />
<br/>
<label>密码</label>
<input type="text" id="password" name="password" />
<br/><br/>
<button οnclick="function(){document.getElementById('form').submit();}">登录</button>
</form> -->
<!-- ajax请求 -->
<label>用户名</label>
<input type="text" id="name" name="name" />
<br />
<label>密码</label>
<input type="text" id="password" name="password" />
<br />
<br />
<button οnclick="login()">登录</button>
<button οnclick="getAll()">查询</button>
<span id="msg"></span>
<br />
<br />
<div id="div">
</div>
</body>
</html>
八,新增getAll()方法:
function getAll() {
// 获取XmlHttpRequest对象
var xhr = getXmlHttpRequest();
xhr.open('get', '/webDemo/send_ajax', false);
//设置请求头
xhr.setRequestHeader("Content-Type","application/json");
xhr.onreadystatechange=function(){
//编写相应的处理代码
if(xhr.readyState == 4){
//只有readyState等亍4,xhr才完整地接收到了服务器返回的数据。
if (xhr.status == 200) {
//获得文本数据,json字符串格式
var txt = xhr.responseText;
//json转换成js对象
var data = JSON.parse(txt);
//dom操作、表格显示数据
var start = "<table width='600px' border='1' cellspacing='0' cellpadding='0'><thead><tr><td>用户名</td><td>用户密码(已加密)</td></tr></thead><tbody>";
var end = "</tbody></table>";
var mid = "";
for (i in data) {
var userInfo = data[i];
var tbody = "<tr><td>"+userInfo.name+"</td><td>"+userInfo.password+"</td></tr>";
mid += tbody;
}
var table = start+mid+end;
document.getElementById('div').innerHTML=table;
} else {
document.getElementById('msg').innerHTML="系统错误";
}
}
};
xhr.send();
}
九,完善doGet请求:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置响应格式
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
UserInfo userInfo1 = new UserInfo();
userInfo1.setName("张三");
userInfo1.setPassword(MD5.getEncryption("123"));
UserInfo userInfo2 = new UserInfo();
userInfo2.setName("李四");
userInfo2.setPassword(MD5.getEncryption("456"));
List<UserInfo> list = new ArrayList<UserInfo>();
list.add(userInfo1);
list.add(userInfo2);
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.INDENT_OUTPUT, Boolean.TRUE);
String json = mapper.writeValueAsString(list);
//获取输出流
PrintWriter out = resp.getWriter();
out.println(json);
out.flush();
out.close();
}
十,访问测试:http://localhost:8088/webDemo/login.html
点击查询,返回结果:
1) 大家应该有注意到,servlet-mapping 这里设置的是“/send_ajax”,
也就是说只有以“/send_ajax”结尾的请求才能访问到AjaxServlet,根据post,get 请求自动匹配相应的doPost,doGet 方法
2) 前后端交互传递数据,这里使用json字符串格式,
如果从前端需要传递参数到后台,需要将js对象data转换成json格式,JSON.stringify(data)
从后台接收到的json格式数据也需要转换成js对象才能使用,data = JSON.parse(xhr.responseText);
3) 上面说的是如何在js里转换json,在java代码里我们如何转换呢?常用依赖包有jackson 和 fastjson,相关api 我们下篇再详解。