在京东购物时,需要填写我们的地址,我们的步骤是这样的:从下拉框选择省份,紧接着在城市一栏出现了该省份的所有城市供选择,原来在我们每选择一个省份的时候,客户端就会和服务器发生一次小交互。本项目就是做一个省市区联动的效果。

视频演示

链接:https://pan.baidu.com/s/1xwFCtxY3MCJ63Ddcf1EXsA
提取码:1111

项目目录结构

源代码

 
index.jsp


<%--
  Created by IntelliJ IDEA.
  User: 123456
  Date: 2020/8/26
  Time: 11:20
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>省市联动</title>
</head>
<script>
    /**
     * 在文档加载完之后,得到所有的省份
     * 选择了新的省份时,得到该省份的<province>元素
     * 解析xml文档
     *
     * */
    var createXMLHttpRequest = function () {
        try {
            // 适用于大多数浏览器
            return new XMLHttpRequest();
        } catch (e) {
            try {
                // IE6.0
                return new ActiveXObject("Msxml2.XMLHttp");
            } catch (e) {
                try {
                    // IE5.0及以下
                    return new ActiveXObject("Microsoft.XMLHttp");
                } catch (e) {
                    alert("浏览器不支持");
                    return e;
                }
            }
        }
    }
    /**
     * 当页面加载完时,执行
     * */
    window.onload = function () {
        /**
         * ajax的四步操作,获取所有省份的名称
         * 使用每个省份名称创建一个<option>元素,添加到省份下拉框中
         * */
        var xmlHttp = createXMLHttpRequest();
        // 打开连接,三个参数依次是请求方式、请求的servlet、是否异步
        xmlHttp.open("GET", "GetProvince", true);
        // 发送,get方式要传null
        xmlHttp.send(null);
        // 为onreadystatechange添加监听
        xmlHttp.onreadystatechange = function () {
            // (如果服务器响应完成 && 客户端接收到来自服务器的信息)
            if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                // 获取来自服务器的文本
                var text = xmlHttp.responseText;
                // 分割省市名称
                var arr = text.split(",");
                // 循环遍历省份名称,添加到<option>
                for (var i = 0; i < arr.length; i++) {
                    // 创建一个元素
                    var newOption = document.createElement("option");
                    // 设置value:真实值,设置显示的文本内容
                    newOption.value = arr[i];
                    var textNode = document.createTextNode(arr[i]);
                    // 将要显示的文本值传给option
                    newOption.appendChild(textNode);
                    // 将option添加到下拉框
                    document.getElementById("province").appendChild(newOption);
                }
            }
        }
        /**
         * 给省份下拉框添加监听
         * 请求服务器 得到城市名称
         * */
        // 得到省份这个元素
        var province = document.getElementById("province");
        // 为省份元素添加监听
        province.onchange = function () {
            // 获取xmlHttpRequest()
            var xmlHttp = createXMLHttpRequest();
            // 三个参数(请求方式、要请求的servlet、是否异步)
            xmlHttp.open("POST", "GetCity", true);
            // 因为是POST请求方式,要设置响应头
            xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            // 发送省的名称
            xmlHttp.send("provinceName=" + province.value);
            // 为onreadystatechange添加监听
            xmlHttp.onreadystatechange = function () {
                //  (如果服务器响应完成 && 客户端接收到来自服务器的信息)
                if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                    // 删除已有的option,第一个不删除
                    var citySelect = document.getElementById("city");
                    var cityList = citySelect.getElementsByTagName("option");
                    while (cityList.length > 1) {
                        citySelect.removeChild(cityList[1]);
                    }
                    // 获取来自服务器的文本值
                    var result = xmlHttp.responseText;
                    // 分割
                    var arr = result.split(",");
                    // 遍历创建option
                    for (var i = 0; i < arr.length; i++) {
                        var newOption = document.createElement("option");
                        // 设置option的真实值
                        newOption.value = arr[i];
                        // 设置option的显示值
                        var textNode = document.createTextNode(arr[i]);
                        // 将显示值添加到option
                        newOption.appendChild(textNode);
                        // 将option添加到下拉框
                        document.getElementById("city").appendChild(newOption);
                    }
                }
            }
        }
        /**
         * 给省份和城市下拉框添加监听
         * 请求servlet 得到区域名称
         * 遍历区域名称并将其添加到下拉框中
         * */
        var city = document.getElementById("city");
        city.onchange = function () {
            var xmlHttp = createXMLHttpRequest();
            xmlHttp.open("POST", "GetArea", true);
            xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            xmlHttp.send("cityName=" + city.value + "&provinceName=" + document.getElementById("province").value);
            xmlHttp.onreadystatechange = function () {
                if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                    // 移除已有的选项
                    var areaEle = document.getElementById("area");
                    var areaList = areaEle.getElementsByTagName("option");
                    while (areaList.length > 1) {
                        areaEle.removeChild(areaList[1]);
                    }
                    // 获取到来自服务器端的XML文件
                    var areas = xmlHttp.responseXML;
                    // 获得所有的区域
                    var areaEleList = areas.getElementsByTagName("area");
                    for (var i = 0; i < areaEleList.length; i++) {
                        // 获得区域属性——名称name
                        var areaName = areaEleList[i].getAttribute("name");
                        // 创建option
                        var option = document.createElement("option");
                        option.value = areaName;
                        var textNode = document.createTextNode(areaName);
                        option.appendChild(textNode);
                        document.getElementById("area").appendChild(option);
                    }
                }
            }
        }
    }
</script>
<body>
<div align="center">
    <h1>省市区联动</h1>
    省份:<select id="province">
    <option value="省份" selected="selected">===请选择省份===</option>
</select>
    城市:<select id="city">
    <option value="城市" selected="selected">===请选择城市===</option>
</select>
    区域:<select id="area">
    <option value="区域" selected="selected">===请选择区域===</option>
</select>
</div>
</body>
</html>

 

 
 


 
 
GetProvinceServlet类


package com.servlet;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
@WebServlet("/GetProvince")
public class GetProvinceServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /**
         * 得到所有的省份,使用逗号分隔
         * */
        response.setContentType("text/html;charset=utf-8");
        request.setCharacterEncoding("utf-8");
        // 得到Document对象
        SAXReader saxReader = new SAXReader();
        try {
            InputStream inputStream = this.getClass().getResourceAsStream("/china.xml");
            Document document = saxReader.read(inputStream);
            // 查询所有的province,得到属性对象
            List<Attribute> list = document.selectNodes("//province/@name");
            StringBuilder stringBuilder = new StringBuilder();
            // 将省份变成字符串
            for (int i = 0; i < list.size(); i++) {
                stringBuilder.append(list.get(i).getValue());
                if(i < list.size() - 1){
                    stringBuilder.append(",");
                }
            }
            // 响应
            response.getWriter().print(stringBuilder);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }
}

 
 


 
GetCityServlet类


package com.servlet;
import org.dom4j.*;
import org.dom4j.io.SAXReader;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
@WebServlet("/GetCity")
public class GetCityServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /**
         * 1. 获取省份名称
         * 2. 使用省份名称查询到对应的<province>元素
         * 3. province元素转换成字符串
         * 4. 响应
         * */
        response.setContentType("text/html;charset=utf-8");
        request.setCharacterEncoding("utf-8");
        // 得到Document对象
        SAXReader saxReader = new SAXReader();
        try {
            InputStream inputStream = this.getClass().getResourceAsStream("/china.xml");
            Document document = saxReader.read(inputStream);
            // 获取省份的名称
            String provinceName = request.getParameter("provinceName");
            List<Attribute> city = document.selectNodes("//province[@name='" + provinceName + "']//city/@name");
            // 将元素转换成字符串
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < city.size(); i++) {
                stringBuilder.append(city.get(i).getValue());
                if(i < city.size() - 1){
                    stringBuilder.append(",");
                }
            }
            response.getWriter().print(stringBuilder);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }
}

 

 
 


 
GetAreaServlet类


package com.servlet;
/**
 * 根据省份名称、城市名称,获取区域名称
 * 并将区域名称以xml文件的形式发送给客户端
 * */
import org.dom4j.*;
import org.dom4j.io.SAXReader;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
@WebServlet("/GetArea")
public class GetAreaServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/xml;charset=utf-8");
        SAXReader saxReader = new SAXReader();
        String provinceName = request.getParameter("provinceName");
        String cityName = request.getParameter("cityName");
        try {
            InputStream inputStream = this.getClass().getResourceAsStream("/china.xml");
            Document document = saxReader.read(inputStream);
            Element element = (Element) document.selectSingleNode("//province[@name='" + provinceName + "']" + "//city[@name='" + cityName + "']");
            String areas = element.asXML();
            response.getWriter().print(areas);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }
}

 

 


 

源文件:location(点击下载)


代码编译器:IntelliJ IDEA 20.02
 
 

您必须 登录 才能发表评论