业务分析:
1.JSP
>省份:
<select name="province">
<option>===请选择省份===</option>
</select>
>城市:
<select name="city">
<option>===请选择城市===</option>
</select>
2.Servlet
2.1ProvinceServlet:
当页面加载完成后立马请求这个Servlet.(它需要加载china.xml文件,把所有省份的名称使用字符串发送给客户端)
页面工作:
获取这个字符串,使用逗号分隔,得到数组.
循环遍历每个字符串(省份的名称),使用每个字符串创建一个<option>元素添加到<select name="province">这个元素中
2.2CityServlet:
当页面选择某个省份时,发送请求(得到省份名称时,加载china.xml文件,查询出该省份对应的元素对象,把这个元素对象转换成xml字符串,发送到客户端)
页面工作:
把<selevt name="city">中的所有元素删除,但不删除<option>===请选择城市===</option>
得到服务器响应结果:doc!
获取所有<city>子元素,循环遍历,得到<city>的内容
使用每个city的内容创建一个<option>元素,添加到<select name ="city">
代码:
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>省市联动</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");
} catch (e) {
try {
return new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
}
}
}
}
/*
* 1.在文档加载完毕时,发出请求,得到所有省份名称,显示在<select name ="province/>"中
2.在选择了新的省份时,发送请求(参数名为省名称),得到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;
//使用逗号分隔
var arr = text.split(",");
//循环遍历每个省份,每个名字生成一个option对象,添加到<select>中
for(var i =0;i<arr.length;i++){
var op = document.createElement("option");//创建一个指定名称元素
op.value = arr[i];//设置实际值为当前的省份名称
var textNode = document.createTextNode(arr[i]);//创建文本节点
op.appendChild(textNode);//把文本节点添加到op元素中,指定其显示值
document.getElementById("p").appendChild(op);
}
}
};
/*
第二件事:给<select name="province">添加改变监听
使用选择的省份名称请求CityServlet,得到<province>元素(xml元素)
使用每个市名称创建<option>元素添加到<select name="city">
*/
var proSelect = document.getElementById("p");
proSelect.onchange = function(){
/*
ajax四步:
请求provinceServlet,得到所有省份名称
使用每个省份名称创建一个<option>元素,添加到<Select name="province">中
*/
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");
//循环遍历每个option元素,在citySelect中移除
while(optionEleList.length >1){//元素个数大于1就移除
citySelect.removeChild(optionEleList[1]);//总是删除1下标,因为1删除了,下一个元素上移为1
}
var doc = xmlHttp.responseXML;
//得到所有名为city的元素
var cityEleList = doc.getElementsByTagName("city");
for(var i=0;i<cityEleList.length;i++){
var cityEle = cityEleList[i];
var cityName;
if(window.addEventListener){//处理浏览器差异
cityName = cityEle.textContent;//其他liulanqi
}else{
cityName = cityEle.text;//IE
}
var op = document.createElement("option");
op.value = cityName;//显示的实际值
//创建文本节点
var textNode = document.createTextNode(cityName);
op.appendChild(textNode);//把文本节点追加到option
//添加op到select中
citySelect.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:
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.io.SAXReader;
public class ProvinceServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
/*
* 响应所有省份名称,使用逗号隔开
*/
/*
* 1.Document对象
* *创建解析器对象
* *调用解析器的读方法,传递一哥流对象,得到Document
*/
try{
SAXReader reader = new SAXReader();
InputStream input = this.getClass().getResourceAsStream("/china.xml");
Document doc = reader.read(input);
/*
* 查询所有province的name属性,得到一堆的属性对象
* 循环遍历,把所有的属性值连接成一个字符串,发送给客户端
*/
List<Attribute> arrList = doc.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(Exception e){
throw new RuntimeException(e);
}
}
}
CityServlet:
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.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时下面改成xml
response.setContentType("text/xml;charset=utf-8");
/**
* 1.获取省份名称
* 2.使用省份名称查找到对应的<province>元素
* 3.把<province>元素转换成字符串,发送!
*/
try{
//得到document
SAXReader reader = new SAXReader();
InputStream input = this.getClass().getResourceAsStream("/china.xml");
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){
throw new RuntimeException(e);
}
}
}
动图效果:
jar包:
所需jar包及china.xml下载:点击下载