XML解析实现AJAX省市联动
AJAX
Asynchronous JavaScript And XML 异步JavaScript和XML
浏览器是把请求发送到XMLHttpRequest异步对象之中,异步对象对请求进行封装,然后再与发送给服务器。服务器并不是以转发的方式响应,而是以流的方式把数据返回给浏览器,实现局部刷新效果。
Ajax简要使用步骤
1.得到XMLHttpRequest:
<script type="text/javascript">
var httpRequest;
if(window.XMLHttpRequest) {
//在IE6以上的版本以及其他内核的浏览器(Mozilla)等
httpRequest = new XMLHttpRequest();
}else if(window.ActiveXObject) {
//在IE6以下的版本
httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
</script>
2.打开与服务器的连接
xmlHttp.open( ):
>请求方式:GET/POST
>请求的URL:指定服务器资源,提交的地址
>请求是否异步:true发送异步请求,否则为同步请求
xmlHttp.open("GET", "/xxx/xxServlet", true);
3.发送请求
xmlHttp.send(null)
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"); //POST
>参数:就是请求体的内容,如果是GET则必须给出null,否则可能部分浏览器无法发送
如果发送请求时需要带有参数,一般都用POST请求xmlHttp.send (key=value&key=value)
4.注册监听器:onreadystatechange
xmlHttp对象一共有5个状态:
>0:刚创建,未调用open()方法
>1:请求开始,调用了open(),未调用send()
>2:调完send()
>3:服务器开始响应,不代表结束
>4:服务器响应结束
得到xmlHttp对象的状态:
var state = xnlHttp.readyState;/0,1,2,3,4
得到服务器响应的状态:
var status = xmlHttp.status //200,404,500…
得到服务器响应的内容:
var content = xmlHttp.responseText;//得到服务器文本格式的内容
var content = xmlHttp.responseXML;//得到服务器xml格式响应,是Document对象
xmlHttp.onreadystatechange = function(){
if(xmlHttp.readystate ==4 && xmlHttp.status== 200) {
var text = xmlHttp.responseText;
}
}
XML
Extensiable markup language 可扩展标记语言
>可扩展:标签可自定义
>版本:1.0 1.1 一般使用1.0 (1.1不可向下兼容)
>用途:主要为了存储数据
>应用:不同系统间数据传输 表示有关系的数据 配置文件
XML文档声明
<?xml version="1.0" encoding="UTF-8"?>
XML的解析方式
>DOM:树形结构,方便增删改,文件过大易造成内存溢出。
>SAX:事件驱动,从上到下,边读边解析,实现查询,不可增删改。
SAX与DOM解析器:JAXP DOM4J(开发多) JDOM
省市联动
个人实现思路
province.Jsp在加载时,请求ProvinceServlet,对存有省市数据的XML使用DOM4J解析得到各个省名,用逗号拼接返回至JSP,
JSP对返回的字符串分片得到省名列表,遍历列表依次创建元素(option)添加至省的选择框(select),完成省名的加载后,
根据使用者的选择,JSP根据省份对应的value请求CityServlet,解析XML通过XPATH得到value对应的省份信息,以XML格式返回至JSP,最后根据(City标签)得到对应的值,添加至城市的select。
由于每选择一次省名,城市的选项中会添加该省对应的城市,所以在得到城市名之前删除之前生成的结点。
ProvinceServlet
@WebServlet("/ProvinceServlet")
public class ProvinceServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
try {
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
SAXReader saxReader = new SAXReader();
Document document = saxReader.read("C:\\Users\\MajorTom\\IdeaProjects\\TomcatServlet\\web\\province.xml");
List<Attribute> nodes = document.selectNodes("//Province/@Name");
StringBuilder provinces = new StringBuilder();
for (int i = 0; i < nodes.size(); i++) {
provinces.append(nodes.get(i).getValue());
System.out.println(nodes.get(i).getValue());
if (i < nodes.size() - 1) {
provinces.append(",");
}
}
resp.getWriter().write(String.valueOf(provinces));
} catch (Exception e) {
e.printStackTrace();
}
}
}
CityServlet
@WebServlet("/cityServlet")
public class CityServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/xml;charset=UTF-8");
try {
SAXReader saxReader = new SAXReader();
Document document = saxReader.read("C:\\Users\\MajorTom\\IdeaProjects\\TomcatServlet\\web\\province.xml");
String pname = req.getParameter("pname");
Element pro = (Element) document.selectSingleNode("//Province[@Name='" + pname + "']");
String proEle = pro.asXML();
resp.getWriter().write(proEle);
} catch (Exception e) {
e.printStackTrace();
}
}
province.Jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>AjaxTest</title>
<script type="text/javascript">
window.onload = function () {
var xmlHttp;
if (window.XMLHttpRequest) {//浏览器兼容
xmlHttp = new XMLHttpRequest();
} else {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlHttp.open("GET", "/provinceServlet", true);
xmlHttp.send(null);
xmlHttp.onreadystatechange = function () {
if (xmlHttp.status == 200 && xmlHttp.readyState == 4) {//状态判断
var text = xmlHttp.responseText;
var arr = text.split(",");//分隔得到各省名
for (var i = 0; i < arr.length; i++) {
var optionElement = document.createElement("option");//创建标签
optionElement.value = arr[i];//标签值
var node = document.createTextNode(arr[i]);//创建文本
optionElement.appendChild(node);//标签添加文本
document.getElementById("p").appendChild(optionElement);//添加至省份select
}
}
}
var proSelect = document.getElementById("p");//省份select
proSelect.onchange = function () {//省份改变监听
var xmlHttp;
if (window.XMLHttpRequest) {
xmlHttp = new XMLHttpRequest();
} else {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlHttp.open("POST", "/cityServlet", true);
xmlHttp.setRequestHeader("content-Type", "application/x-www-form-urlencoded");
xmlHttp.send("pname=" + proSelect.value);//下拉列表值
xmlHttp.onreadystatechange = function () {
if (xmlHttp.status == 200 && xmlHttp.readyState == 4) {
var citySelect = document.getElementById("c");//城市select
var optionEleList = citySelect.getElementsByTagName("option");//城市option
while (optionEleList.length > 1) {
citySelect.removeChild(optionEleList[1]);//更改省份时移除之前添加的option
}
var doc = xmlHttp.responseXML;//得到CityServlet传值
var cityEleList = doc.getElementsByTagName("City");//得到city元素列表
for (var i = 0; i < cityEleList.length; i++) {
var cityELe = cityEleList[i];//得到单个元素
var cityName;
if (window.addEventListener) {//浏览器兼容
cityName = cityELe.textContent;
} else {
cityName = cityELe.text;
}
var option = document.createElement("option");
option.value = cityName;
var text = document.createTextNode(cityName);
option.appendChild(text);
document.getElementById("c").appendChild(option);
}
}
}
}
}
</script>
</head>
<body>
<h1>TestAjax</h1>
<select name="province" id="p">
<option>===请选择省份===</option>
</select>
<select name="city" id="c">
<option>===请选择城市===</option>
</select>
</body>
</html>
XML文件及效果