一、前期准备:
china.xml、dom4j和xpath的jar包
ajax5.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'ajax5.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() {
try {
return new XMLHttpRequest();//大多数浏览器都支持
} catch (e) {
try {
return new ActiveXObject("Msxml2.XMLHTTP");//IE6.0支持
} catch (e) {
try {
return new ActiveXObject("Microsoft.XMLHTTP");//IE5.5以及更早的版本支持
} catch (e) {
alert("大哥,你到底用的什么浏览器!");
throw e;
}
}
}
}
/*
请求1
当页面加载完成后,发送第一个请求,
获取到响应的字符串,用逗号分隔,生成一个数组,
遍历这个数组,动态创建<option>元素,添加文本节点,讲<option>添加到<select name="province">中
*/
window.onload = function() {
//Ajax发送GET请求四步:
//1.创建xmlHttpRequest对象
var xmlHttp = createXMLHttpRequest();
//2.打开与服务器的连接
xmlHttp.open("GET", "<c:url value='/ProvinceServlet'/>", true);
//3.发送请求
xmlHttp.send(null);
//4.注册状态监听器
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState==4 && xmlHttp.status==200) {//双重判断
//获取服务器响应的字符串
var text = xmlHttp.responseText;
//生成一个字符串数组
var arrPro = text.split(",");
//获取<select>
var p = document.getElementById("p");
//循环遍历数组
for(var i=0; i< arrPro.length; i++) {
//动态创建<option>
var op = document.createElement("option");
//添加实际值
op.value=arrPro[i];
//创建文本节点
var textNode = document.createTextNode(arrPro[i]);
op.appendChild(textNode);
p.appendChild(op);
}
}
};
/*
请求2
给<select name="province">注册改变监听器
当点击一个省份时,发送请求
得到服务器响应的一个document对象(一个<province name=''>xml格式的字符串)
获取<province>中所有的<city>元素,循环遍历,得到<city>的文本内容
使用每一个<city>的文本内容,创建一个<option>元素,添加到<select name="city">中
*/
var proSelect = document.getElementById("p");
proSelect.onchange = function() {
var xmlHttp = createXMLHttpRequest();
xmlHttp.open("POST", "<c:url value='/CityServlet'/>", true);
xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlHttp.send("pname=" + proSelect.value);
xmlHttp.onreadystatechange = function() {
/*
把<select>中的<option>先移除掉,除了第一个option不移除掉
*/
var citySelect = document.getElementById("c");
//先获取所有的子元素
var cityEleList = citySelect.childNodes;
//一个巧妙的算法:第0个永远不移除掉,永远只移除第一个,每一个会向上顶
while(cityEleList.length>1) {
//每次只移除掉下标为1的元素
citySelect.removeChild(cityEleList[1]);
}
if(xmlHttp.readyState==4&&xmlHttp.status==200){
var xmlDom = xmlHttp.responseXML;
//返回一个指定标签元素的集合
var cityEleList = xmlDom.getElementsByTagName("city");
var c = document.getElementById("c");
for(var i=0; i<cityEleList.length; i++) {
var cityEle = cityEleList[i];
var text;
//处理浏览器获取文本的兼容性问题
if(window.addEventListener) {//true大多数都支持
text = cityEle.textContent;
} else {//IE8及其更早版本支持
text = cityEle.text;
}
var op = document.createElement("option");
op.value=text;
var textNode = document.createTextNode(text);
op.appendChild(textNode);
c.appendChild(op);
}
}
};
};
};
</script>
</head>
<body>
<h1>省市联动</h1>
<select name="province" id="p">
<option>===请选着省===</option>
</select>
<select name="city" id="c">
<option>===请选择市===</option>
</select>
</body>
</html>
ProvinceServlet.java
package cn.itcast.web.servlet;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
public class ProvinceServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
/*
* 获取china.xml文件中所有的<province name=''>的name属性的值,连接成为字符串,用逗号隔开,响应给客户端
*/
//创建解析器对象(先导入dom4j和xpath的jar包)
SAXReader saxReader = new SAXReader();
//创建一个输入流
InputStream in = this.getClass().getResourceAsStream("/china.xml");
try {
//得到document对象
Document dom = saxReader.read(in);
//获取所有的省份的name集合
List<Attribute> list = dom.selectNodes("//province/@name");
StringBuilder sb = new StringBuilder();
for(int i=0; i < list.size(); i++) {
sb.append(list.get(i).getValue());//获取每个属性的值添加到sb
if(i< list.size() -1) {
sb.append(",");
}
}
response.getWriter().print(sb);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
CityServlet.java
package cn.itcast.web.servlet;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
public class CityServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/xml;charset=utf-8");//当响应内容为xml时,不要忘记修改
/*
* 获取客户端传来的省份参数,
* 加载china.xml文件,根据参数的内容来查找对应的<province>元素
* 吧这个元素转换成xml字符串,响应给客户端
*/
String pname = request.getParameter("pname");
SAXReader saxReader = new SAXReader();
InputStream in = this.getClass().getResourceAsStream("/china.xml");
try {
Document doc = saxReader.read(in);
Node proEle = doc.selectSingleNode("//province[@name='" + pname + "']");
String xmlStr = proEle.asXML();
System.out.println(xmlStr);
response.getWriter().print(xmlStr);
} catch (DocumentException e) {
throw new RuntimeException(e);
}
}
}
效果图: