目的:
客户端通过ajax请求服务器端获得xml文件中的各省的名称,通过选择省,再加载市的名称
效果:
代码实现
导入jar包
- dom4j-1.6.1.jar
- jaxen-1.1-beta-6.jar
在src下放入省市文件china.xml
建立ProvinceServlet.java
@WebServlet(name = "ProvinceServlet",urlPatterns = "/ProvinceServlet")
public class ProvinceServlet extends HttpServlet {
/**
*
* 响应所有省份名称,使用逗号隔开
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
/**
* 获取china.xml中的省
* 使用xpath查询
*
* 1、创建解析器对象
* 2、获取china.xml文件流
* 3、调用解析器的读方法,得到Document对象
*/
try {
SAXReader reader=new SAXReader();
//获取china.xml文件流,路径注意
InputStream in=this.getClass().getResourceAsStream("/china.xml");
Document doc = reader.read(in);
/**
* 查询所有provice的name属性,得到以堆的属性对象
* 循环遍历,把所有属性值连成一个字符串,返回给客户端
*/
//通过xpath查询xml文件中结点为provice的name属性值,返回一个Attribute数列
List<Attribute> attributeList = doc.selectNodes("//province/@name");
StringBuilder sb=new StringBuilder();
for(int i=0;i<attributeList.size();i++){
sb.append(attributeList.get(i).getValue());//将省份名称添加到sb字符串中
if(i<attributeList.size()-1){//添加逗号分割
sb.append(",");
}
}
response.getWriter().print(sb);//发送给客户端
} catch (DocumentException e) {
throw new RuntimeException(e);
}
}
}
CityServlet.java
@WebServlet(name = "CityServlet",urlPatterns = "/CityServlet")
public class CityServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/xml;charset=utf-8");
request.setCharacterEncoding("utf-8");
/**
* 通过xpath查询:dom4j包中的document
* 1、获得解析器对象
* 2、获得china.xml文件流
* 3、调用解析器的读方法获得document对象
* 4、调用xpath查询
*/
try {
SAXReader reader=new SAXReader();
InputStream in = this.getClass().getResourceAsStream("/china.xml");
Document doc = reader.read(in);
//获取省份名称参数
String pname = request.getParameter("province");
//查询名为pname的省份
Element ele = (Element) doc.selectSingleNode("//province[@name='"+pname+"']");
String s = ele.asXML();//将xml对象转化为字符串
//发送给客户端
response.getWriter().print(s);
}catch (Exception e){
throw new RuntimeException(e);
}
}
}
province_city_show.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>省市联动</title>
<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;
}
}
}
}
//文档被加载完时调用
window.onload=function () {
/**
* get方式:Ajax四步
* 1、获取XMLHttpRequest对象
* 2、打开服务器连接
* 3、发送请求
* 4、onreadystatechange监听状态,获取服务器响应
*/
var httpRequest = CreateXMLHttpRequest();
httpRequest.open("get","<c:url value='/ProvinceServlet'/>",true);
httpRequest.send(null);
httpRequest.onreadystatechange=function () {
if(httpRequest.readyState==4&&httpRequest.status==200){
//获取服务器响应内容
var text = httpRequest.responseText;
//获得provice对象
var selectProvince = document.getElementById("p");
//将省份字符串去除逗号,得到名称数组
var arr = text.split(",");
//遍历数组
for (var i = 0; i <arr.length ; i++) {
//新建选项元素
var opt = document.createElement("option");
opt.value=arr[i];//设置opt的实际值为身份名称
//创建文本结点,值为省份名
var node = document.createTextNode(arr[i]);
opt.appendChild(node);//将文本结点添加到选项元素中
selectProvince.appendChild(opt);//添加到省份选择框中
}
}
};
/**
* 第二件事:当选择省份select时,将省份名称作为参数传递给cityServlet,获取该省份的xml(包含市名称)
* 使用select的onchange事件
*/
//获取省份select
var selectProvince = document.getElementById("p");
selectProvince.onchange=function () {
//得到城市select对象
var cSelect = document.getElementById("c");
//清除选项框中的内容
var optElementArr = cSelect.getElementsByTagName("option");//获取选择框中的所有元素
while(optElementArr.length>1){
cSelect.removeChild(optElementArr[1]);//每次移除第二个元素,保留第一个提示信息
}
/**
* post:ajax5步
* 1、得到xmlhttprequest对象
* 2、打开服务器连接
* 3、设置请求头
* 4、发送请求
* 5、监听响应
*/
var httpRequest=CreateXMLHttpRequest();
httpRequest.open("post","<c:url value='/CityServlet'/>",true);
httpRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
httpRequest.send("province="+selectProvince.value);
httpRequest.onreadystatechange=function () {
if(httpRequest.readyState==4&&httpRequest.status==200){
//获得document对象
var doc = httpRequest.responseXML;
//获取所有名为city的值,得到的一个数组
var cityArr = doc.getElementsByTagName("city");
for (var i = 0; i <cityArr.length ; i++) {
var city = cityArr[i];//得到每个元素
var cityName;
//考虑浏览器差异化
if (window.addEventListener) {
cityName=city.textContent;//多数浏览器
}else{
cityName=city.text;//ie
}
//创建选项元素
var optionElement = document.createElement("option");
optionElement.value=cityName;//设置真实值
var node = document.createTextNode(cityName);
optionElement.appendChild(node);//添加显示值
cSelect.appendChild(optionElement);//添加到选择框中
}
}
};
}
};
</script>
</head>
<body>
<h1>省市联动</h1>
<select id="p" name="province">
<option>===请选择省===</option>
</select>
<select id="c" name="city">
<option>===请选择市===</option>
</select>
</body>
</html>
代码中的注释都很详细,具体过程就不在说明。