演示视频
ajax实现的省市联动 演示视频
前端页面 demo.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>Ajax实现的省市联动Demo</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浏览器
} catch (e) {
try {
return new ActiveXObject("Microsoft.XMLHTTP"); //支持IE5.5以及更早版本的浏览器
} catch (e) {
alert("不支持您的浏览器!");
throw e;
}
}
}
}
//在文档加载完毕时发送请求,得到所有的省份名称,显示在<select name="province">中
// 在选择了新的省份之后,发送请求(参数为省名称),得到xml文档,即<province>元素
// 解析xml文档,得到其中所有的city,再得到每个<city>元素的内容,即市名,使用市名生成<option>元素,并且插入到<select>中
window.onload = function() {
// Ajax四步:请求ProvinceServlet,得到所有的省份名称
// 使用每一个省份创建一个<option>元素,添加到<select name="province">中
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;
// 使用逗号分割,得到数组
if (text) {
var arr = text.split(",");
}
// 循环遍历每个省份的名称,每个名称生成一个option对象,添加到<select>
for (var i = 0; i < arr.length; i++) {
// 创建一个指名名称的元素
var op = document.createElement("option");
// 设定op的实际值为当前的省份名称
op.value = arr[i];
// 创建一个文本节点
var textNode = document.createTextNode(arr[i]);
// 把文本子节点添加到op元素中
op.appendChild(textNode);
document.getElementById("p").appendChild(op);
}
};
// 给<select>添加改变监听器
// 使用选择的省份名称请求CityServlet,得到<province>元素(xml元素)
// 获取<province>元素中所有的<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() {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
//把所有的select中的option清除掉( 除了请选择)
var citySelect = document.getElementById("c");
var optionEleList = citySelect
.getElementsByTagName("option");
while (optionEleList.length > 1) {
citySelect.removeChild(optionEleList[1]);
}
var doc = xmlHttp.responseXML;
// 得到所有名为city的元素
var cityEleList = doc.getElementsByTagName("city");
// 循环遍历每个city元素
for (var i = 0; i < cityEleList.length; i++) {
// 得到每个city元素
var cityEle = cityEleList[i];
var cityName;
// 处理浏览器兼容性问题
if (window.addEventListener) {
cityName = cityEle.textContent;
} else {
cityName = cityEle.text;
}
// 使用城市名称创建option元素,添加到select元素中。
var op = document.createElement("option");
op.value = cityName;
// 创建文本节点
var textNode = document.createTextNode(cityName);
op.appendChild(textNode);
var citySelect = document.getElementById("c");
citySelect.appendChild(op);
}
}
};
};
};
</script>
</head>
<body>
<select name="province" id="p">
<option>===请选择省份===</option>
</select>
<select name="city" id="c">
<option>===请选择城市===</option>
</select>
</body>
</html>
后台Servlet
1.ProvinceServlet
package com.veeja.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.DocumentException;
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");
/*
* 响应所有省份名称,省份之间用逗号隔开
*/
try {
// 创建一个解析器对象,调用解析器的读方法,传递一个流对象,得到Document
SAXReader reader = new SAXReader();
InputStream input = this.getClass().getResourceAsStream(
"/china.xml");
Document document = reader.read(input);
// 查询所有的province的name属性,得到一堆的属性对象
// 循环遍历,把所有的属性值连接成一个字符串,发送给客户端
List<Attribute> arrList = document.selectNodes("//province/@name");
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 (DocumentException e) {
throw new RuntimeException(e);
}
}
}
2. CityServlet
package com.veeja.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.io.SAXReader;
public class CityServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
// 注意,这里要改成XML
response.setContentType("text/xml;charset=utf-8");
/*
* 获取省份名称,加载该省份对应的<province>元素。
*
* 把元素转换成字符串发送给客户端。
*/
// 获取省份名称,使用省份名称查找到对应的<province>元素,
// 把<province>元素转换成字符串,发送。
try {
// 创建一个解析器对象,调用解析器的读方法,传递一个流对象,得到Document
SAXReader reader = new SAXReader();
InputStream input = this.getClass().getResourceAsStream(
"/china.xml");
Document document = reader.read(input);
// 获取省份名称
String pname = request.getParameter("pname");
System.out.println(pname);
Element proEle = (Element) document
.selectSingleNode("//province[@name='" + pname + "']");
// 把元素转换为字符串
System.out.println(proEle);
String xmlStr = proEle.asXML();
response.getWriter().print(xmlStr);
} catch (DocumentException e) {
throw new RuntimeException(e);
}
}
}
END.