本文主要是在JavaWeb中如何使用Ajax,是属于原生的使用方法,不涉及jQuery等知识,是直接利用JavaScript进行与Web服务器进行交互;
1、AJAX
2、AJAX基础实现与应用
3、AJAX省市联动实现与应用
1、AJAX(摘自百度百科文章)
- 同步交互与异步交互
- 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
- 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。
- 什么是AJAX
AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和 XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。
AJAX还有一个最大的特点就是,当服务器响应时,不用刷新整个浏览器页面,而是可以局部刷新。这一特点给用户的感受是在不知不觉中完成请求和响应过程。- 应用场景:
- 与服务器异步交互;
- 浏览器页面局部刷新;
2、AJAX基础实现与应用
ajax发送一步请求最基本的做法(最结为四个主要步骤):ajax发送异步请求(四步操作)
1、第一步(得到XMLHttpRequest)
大多数浏览器都支持:var xmlHttp = new XMLHttpRequest();
IE6.0:var xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
IE5.5以更早版本的IE:var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
创建 XMLHttpRequest对象的函数
function createXMLHttpRequest() {
try {
return new XMLHttpRequest();
} catch(e) {
try {
return new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
try {
return new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
alert("无法识别使用的浏览器,AJAX可能失效");
throw e;
}
}
}
}
2、第二步(打开与服务器的连接)
- xmlHttp.open():用来打开与服务器的连接,它需要三个参数:
请求方式:可以是GET或POST
请求的URL:指定服务器端资源,例如;/DemoAJAX/AServlet
请求是否为异步:如果为true表示发送异步请求,否则同步请求!
xmlHttp.open("GET", "/DemoAJAX/AServlet", true);
3、 第三步(发送请求)
- 当使用open打开连接后,就可以调用XMLHttpRequest对象的send()方法发送请求了。
- send()方法的参数为POST请求参数,即对应HTTP协议的请求体内容,若是GET请求,需要在URL后连接参数。
- 若没有参数,需要给出null为参数!若不给出null为参数,可能会导致FireFox浏览器不能正常发送请求!
- xmlHttp.send(null):如果不给可能会造成部份浏览器无法发送!
4、 第四步(接收服务器响应)
- xmlHttp对象的一个事件上注册监听器:onreadystatechange
- xmlHttp对象一共有5个状态:
N状态 | 所处阶段 | 执行 |
---|---|---|
0状态 | 刚创建 | 只是创建了XMLHttpRequest对象,还未调用open()方法 |
1状态 | 请求开始 | open()方法已调用,但还没调用send()方法 |
2状态 | 请求发送完成状态 | send()方法已调用 |
3状态 | 开始读取服务器响应 | |
4状态 | 读取服务器响应结束 |
- 得到xmlHttp对象的状态:
var state = xmlHttp.readyState;//可能是0、1、2、3、4
- 得到服务器响应的状态码
var status = xmlHttp.status;//例如为200、404、500
- 得到服务器响应的内容
var content = xmlHttp.responseText;//得到服务器的响应的文本格式的内容`
var content = xmlHttp.responseXML;//得到服务器的响应的xml响应的内容,它是Document对象了!
xmlHttp.onreadystatechange = function() {//xmlHttp的5种状态都会调用本方法
if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
//双重判断:判断是否为4状态,而且还要判断是否为200
// 获取服务器的响应内容
var text = xmlHttp.responseText;
}
};
1)AJAX第一例(GET请求)
首先创建一个JavaWeb工程,创建一个Servlet
- AServlet.java
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class AServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
System.out.println("Ajax测试---Hello Ajax");
response.getWriter().print("Ajax测试---Hello Ajax");
}
}
- demo1.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'demo1.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
<script type="text/javascript">
function createXMLHttpRequest() {
var xmlHttp;
try {
return xmlHttp = new XMLHttpRequest();
} catch (e) {
try {
return xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
return xmlHttp = new ActiveXObject("Micrsoft.XMLHTTP");
} catch (e) {
alter("无法识别您的浏览器,将会失去异步传输功能");
throw e;
}
}
}
}
window.onload = function() {
var btn = document.getElementById("btn");
btn.onclick = function() {
//创建对象
var xmlHttp = createXMLHttpRequest();
//打开与服务器的连接
xmlHttp.open("GET","<c:url value='/AServlet' />",true);
//发送请求
xmlHttp.send(null);
//注册监听获取事件状态
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState == 4 && xmlHttp.status == 200){
var h1 = document.getElementById("h1");
h1.innerHTML = xmlHttp.responseText;
}
};
};
};
</script>
</head>
<button id="btn">点击这里</button>
<h1 id="h1"></h1>
<body>
</body>
</html>
2)AJAX第二例(POST请求)
- BServlet.java
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class BServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
String username = request.getParameter("username");
System.out.println("Ajax测试---POST方式:username="+username);
response.getWriter().print("Ajax测试---POST方式:username="+username);
}
}
- demo2.jsp(只给出重要的js代码片段)
<script type="text/javascript">
function createXMLHttpRequest() {
var xmlHttp;
try {
return xmlHttp = new XMLHttpRequest();
} catch (e) {
try {
return xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
return xmlHttp = new ActiveXObject("Micrsoft.XMLHTTP");
} catch (e) {
alter("无法识别您的浏览器,将会失去异步传输功能");
throw e;
}
}
}
}
window.onload = function() {
var btn = document.getElementById("btn");
btn.onclick = function() {
//创建对象
var xmlHttp = createXMLHttpRequest();
//打开与服务器的连接
xmlHttp.open("POST","<c:url value='/BServlet' />",true);
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
//发送请求
var username = document.getElementById("username").value;
xmlHttp.send("username="+username);
//注册监听获取事件状态
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState == 4 && xmlHttp.status == 200){
var h1 = document.getElementById("h1");
h1.innerHTML = xmlHttp.responseText;
}
};
};
};
</script>
- 1
3)AJAX省市联动的例子(省市数据来源一般可以使用XML文件进行存放或者使用数据库进行存放,在本例中使用了XML文件进行存放)
给出部分China.xml文件片段:
<?xml version="1.0" encoding="utf-8"?>
<china>
<province name="北京">
<city>东城区</city>
<city>西城区</city>
<city>崇文区</city>
<city>宣武区</city>
<city>朝阳区</city>
</province>
<province name="香港">
<city>香港</city>
</province>
<province name="澳门">
<city>澳门</city>
</province>
<province name="台湾">
<city>台湾</city>
</province>
</china>
- CityServlet.java
public class CityServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/xml;charset=UTF-8");
/*
* 1、获取省份的名称
* 2、使用省份的名称,并且对于区域进行查找
* 3、转换成字符串进行发送!
*/
try{
SAXReader reader = new SAXReader();//解析器
InputStream input = this.getClass().getResourceAsStream("/china.xml");
org.dom4j.Document doc = reader.read(input);
/*
* 获取参数
*/
String pname = request.getParameter("pname");
Element proEle = (Element) doc.selectSingleNode("//province[@name='"+pname+"']");
String xmlStr = proEle.asXML();
response.getWriter().print(xmlStr);
} catch (Exception e) {
// TODO: handle exception
throw new RuntimeException(e);
}
}
}
- ProvinceServlet.java
public class ProvinceServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@SuppressWarnings("unchecked")
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/xml;charset=UTF-8");
/*
* 1、Doument对象
* *创建解析器对象
* *调用解析器的读方法,传递一个流对象,得到Document
*/
try{
SAXReader reader = new SAXReader();//解析器
InputStream input = this.getClass().getResourceAsStream("/china.xml");
org.dom4j.Document doc = reader.read(input);
System.out.println(doc);
/*
* 查询所有的province的name属性,得到一堆的属性对象
*/
List<Attribute> arrList = doc.selectNodes("//province/@name");//@表示属性
System.out.println(arrList);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < arrList.size() ; i++) {
sb.append(arrList.get(i).getValue());
if (i < arrList.size() - 1) {
sb.append(",");
}
}
response.getWriter().print(sb);
} catch (Exception e) {
// TODO: handle exception
throw new RuntimeException(e);
}
}
@Test
public void demo() throws Exception {
SAXReader reader = new SAXReader();//解析器
InputStream input = this.getClass().getResourceAsStream("/china.xml");
Document doc = reader.read(input);
System.out.println(doc);
}
}
- 前端页面demo3.jsp(代码)
<html>
<head>
<title>My JSP 'demo3.jsp' starting page</title>
<script type="text/javascript">
function createXMLHttpRequest() {
var xmlHttp;
try {
return xmlHttp = new XMLHttpRequest();
} catch (e) {
try {
return xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
return xmlHttp = new ActiveXObject("Micrsoft.XMLHTTP");
} catch (e) {
alter("无法识别您的浏览器,将会失去异步传输功能");
throw e;
}
}
}
}
window.onload = function() {
var xmlHttp = createXMLHttpRequest();
xmlHttp.open("get","<c:url value='/ProvinceServlet'/>",true);
xmlHttp.send(null);
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState == 4 && xmlHttp.status == 200){
var text = xmlHttp.responseText;
var arr = text.split(",");
for(var i = 0;i < arr.length;i++){
//创建指定名称的元素
var option = document.createElement("option");
option.value = arr[i];//设置实际的值
var textNode = document.createTextNode(arr[i]);//创建文本节点
option.appendChild(textNode);//添加文本子节点
document.getElementById("p").appendChild(option);
}
}
};
};
function selectCity(){
var xmlHttp = createXMLHttpRequest();
xmlHttp.open("POST","<c:url value='/CityServlet'/>",true);
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
var pname = document.getElementById("p").value;
xmlHttp.send("pname="+pname);
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState == 4 && xmlHttp.status == 200){
var citySelect = document.getElementById("c");
var optionEleList = citySelect.getElementsByTagName("option");
while(optionEleList.length > 1){
citySelect.removeChild(optionEleList[1]);//总是删除第一个下标,因为删除1了下面的会顶上来
}
var doc = xmlHttp.responseXML;
var cityElementList = doc.getElementsByTagName("city");
for(var i=0;i<cityElementList.length;i++){
var cityElement = cityElementList[i];
var cityName;
if(window.addEventListener) {
cityName = cityElement.textContent;//支持火狐等浏览器
} else{
cityName = cityElement.text;//支持IE
}
var option = document.createElement("option");
option.value = cityName;
var textNode = document.createTextNode(cityName);
option.appendChild(textNode);
//定义在之前:var citySelect = document.getElementById("c");
citySelect.appendChild(option);
}
}
};
}
</script>
</head>
<body>
<h1 id="h1"></h1>
<h1>省市联动</h1>
<select name="province" id="p" onchange="selectCity()">
<option>===请选择省===</option>
</select>
<select name="city" id="c">
<option>===请选择市===</option>
</select>
</body>
</html>