1.功能介绍

  • ajax.jsp页面
<h1>省市联动</h1>
<select name="province" id="p">
    <option>===请选择省===</option>
</select>    
<select name="city" id="c">
    <option>===请选择市===</option>
</select>

Java中怎么做地区的级联_Java中怎么做地区的级联

  • ProvinceServlet:当页面加载完成后,马上请求这个Servlet!它需要加载china.xml文件,把所有的省的名称使用字符串发送给客户端!

ProvinceServlet.java代码如下:

package cn.itcast.web.servlet;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
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 {
	    // 创建解析器
	    SAXReader reader = new SAXReader();
	    InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("china.xml");
	    // InputStream inputStream = this.getClass().getResourceAsStream("/china.xml");
	    // 得到Document文档
	    Document doc = reader.read(inputStream);

	    // xpath查询所有province元素的name属性
	    List<Attribute> attrList = doc.selectNodes("//province/@name");
	    StringBuilder sb = new StringBuilder();
	    // 循环遍历,把所有的name属性值连接成字符串,发送给客户端
	    for (int x = 0; x < attrList.size(); x++) {
		sb.append(attrList.get(x).getValue());
		if (x < attrList.size() - 1) {
		    sb.append(",");
		}
	    }

	    System.out.println(sb);
	    response.getWriter().print(sb);

	} catch (DocumentException e) {
	    e.printStackTrace();
	}
    }

}
  • ajax.jsp页面的工作:获取这个字符串,使用逗号分隔,得到数组。循环遍历每个字符串(省份的名称),使用每个字符串创建一个<option>元素添加到<select name="province">这个元素中。
// 在文档加载完毕时马上执行
window.onload = function() {
    // 得到xmlHttp对象
    var xmlHttp = createXMLHttpRequest();
    // 调用xmlHttp对象的open()方法,打开与服务器的连接
    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 textArr = text.split(",");
	    // 循环遍历每个省份名称
	    for ( var x = 0; x < textArr.length; x++) {
	        var opEle = document.createElement("option");
		opEle.value = textArr[x];
		// 创建文本节点
		var textNode = document.createTextNode(textArr[x]);
		opEle.appendChild(textNode);
		document.getElementById("p").appendChild(opEle);
	    }
	}
    };
};
  • CityServlet:当页面选择某个省份时,发送请求!得到省份的名称,加载china.xml文件,查询出该省份对应的元素对象!把这个元素转换成xml字符串,发送给客户端。

CityServlet.java代码如下:

package cn.itcast.web.servlet;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;

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");
	response.setContentType("text/xml;charset=utf-8");

	/*
	 * Document对象的document.asXML()就是将整个文件组成一个String字符串
	 * Element对象的element.asXML();指的是将这个节点(元素)的开始到结束包含的内容组成String
         */
	try {
	    // 创建解析器
	    SAXReader reader = new SAXReader();
	    InputStream inputStream = this.getClass().getClassLoader()
					.getResourceAsStream("china.xml");
	    // 得到Document对象
	    Document doc = reader.read(inputStream);

	    // 获取省份名称
	    String pname = request.getParameter("pname");
	    // 使用省份名称pname查找对应的<province>元素
	    Element proEle = (Element) doc.selectSingleNode("//province[@name='" + pname + "']");
	    // proEle.asXML()指的是将<province>元素的开始到结束的内容组成String字符串
	    String xmlStr = proEle.asXML();
			
	    response.getWriter().print(xmlStr);
	} catch (DocumentException e) {
	    e.printStackTrace();
	}
    }
}
  • ajax.jsp页面的工作

* 把<select name="city">中的所有子元素删除,但不要删除<option>===请选择市===</option>

* 得到服务器的响应结果:doc!!!

* 获取所有的<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() {
	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就循环,等于1就不循环了!
                citySelect.removeChild(optionEleList[1]);//总是删除1下标,因为1删除了,2就变成1了!
	    }
					
	    var doc = xmlHttp.responseXML;
	    // 得到所有名为city的元素
	    var cityEleList = doc.getElementsByTagName("city");
	    for ( var x = 0; x < cityEleList.length; x++) {
	        // 得到每个city元素
		var cityEle = cityEleList[x];
		// 市名称
		var cityName;
		// 处理浏览器的差异
		if (window.addEventListener) {
		    cityName = cityEle.textContent;
		} else {
		    cityName = cityEle.text;
		}

		// 创建<option>元素,添加到<select name="city">中
		var opEle = document.createElement("option");
		opEle.value = cityName;
		
                // 创建文本节点
		var textNode = document.createTextNode(cityName);
	        opEle.appendChild(textNode);
						
		citySelect.appendChild(opEle);

	    }
        }
    };
};

2.实现效果如下:

Java中怎么做地区的级联_xml_02

Java中怎么做地区的级联_java_03