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文件及效果

posted @ 2021-02-10 17:30  Ho-Yu-Fung  阅读(58)  评论(0编辑  收藏  举报