Ajax

1.什么是Ajax?

  asynchronous javascript and xml:异步的js和xml

  它能使用js访问服务器,而且是异步访问!

  服务器给客户端的响应一般是整个页面,一个html完整页面!但在ajax中因为是局部刷新,那么服务器就不用再响应整个页面!而只是数据!

    >text:纯文本

    >xml:

    >json:它是js提供的数据交互格式,在Ajax中最受欢迎!

2.异步交互和同步交互

  * 同步:

    >发一个请求,就要等待服务器的响应结束,然后才能发第二个请求!中间这段时间就是一个“卡”

    >刷新的是整个页面!

  * 异步:

    >发送一个请求后,无需等待服务器的响应,然后就可以发送第二个请求!

    >可以使用js接收服务器的响应,然后使用js来局部刷新!

3.ajax应用场景

  * 百度的搜索框

  * 用户注册时(校验用户名是否被注册过)

4.ajax的优缺点

  优点:

    * 异步交互:增强了用户体验!

    * 性能:因为服务器无需再响应整个页面,只需要响应部分内容,所以服务器的压力减轻了!

  缺点:

    * ajax不能应用在所有的场景!

    * ajax无端的增多了对服务器的访问次数,给服务器带来了压力!


 

Ajax发送异步请求(四步操作)

1.第一步(得到XMLHttpRequest)

  * ajax其实只需要学习一个对象:XMLHttpRequest,如果掌握了它,就掌握了ajax!!!

  * 得到XMLHttpRequest

    > 大多数浏览器都支持:var xmlHttp = new XMLHttpRequest();

    > IE6.0:var xmlHttp = new ActiveXObject("Msxml2.0XMLHTTP");

    > IE5.5及更早版本的IE:var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");

  * 编写创建XMLHttpRequest对象的函数

        function creatXMLHttpRequest(){
            try {
                return new XMLHttpRequest();
            } catch (e) {
                try {
                    return new ActiveXObject("Msxml2.XMLHTTP");
                } catch (e) {
                    try {
                        return new ActiveXObject("Microsoft.XMLHTTP");
                    } catch (e) {
                        alert("不晓得你用的什么浏览器!");
                        throw e;
                    }
                }
            }
        }

2.第二步(打开与服务器的连接)

  * xmlHttp.open():用来打开与服务器的连接,它需要三个参数:

    > 请求方式:可以是GET或POST

    > 请求的URL:指定服务器端资源,例如:/day23_1/AServlet

    > 请求是否为异步:如果为true表示发送异步请求,否则同步请求!

  *  xmlHttp.open("GET", "/day23_1/AServlet", true);

 3.第三步(发送请求)

  * xmlHttp.send(null):如果不给可能会造成部分浏览器无法发送!

    >参数:就是请求体内容!如果是GET请求,必须给出null。

4.第四步()

  *在xmlHttp对象的一个事件上注册监听器:onreadystatechange

  * xmlHttp对象一共有5个状态:

    > 0状态:刚创建,还没有调用open()方法;

    > 1状态:请求开始,调用了open()方法,但还没有调用send()方法

    > 2状态:调用完了send()方法了;

    > 3状态:服务器已经开始响应,但不表示响应结束了。

    > 4状态:服务器响应结束!(通常我们只关心最后这个状态!!!)

  * 得到xmlHttp对象的状态:

    >  var state = xmlHttp.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(){//xmlHttp的5种状态都会调用本方法
            if(xmlHttp.readyState == 1 && xmlHttp.status == 200){//双重判断:判读是否为4状态,而且还有判断是否为200
                //获取服务器响应内容
                var text=xmlHttp.responseText;
            }
        };

JS示例:

  <head>
    <script type="text/javascript">
        window.onload=function(){//在文档加载完    成之后马上执行!
            //的带btn元素
            var btn=document.getElementById("btn");
            //给btn的click事件注册监听
            btn.onclick=function(){//在按钮被点击时执行!
                //获取h1元素对应的DOM对象
                var h1=document.getElementById("h1");
                //给h1添加内容
                h1.innerHTML="hello JS!!";
            };
        };
    
    </script>

  </head>
  <body>
    <button id="btn">点击这里</button>
    <h1 id="h1"></h1>
  </body>

 


 

Ajax第一例:

AServlet:

package com.xjs.web.servlet;

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

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class AServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("Hello AJAX!");
        response.getWriter().print("Hello AJAX!");
    }
}

ajax1.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://"
            + request.getServerName() + ":" + request.getServerPort()
            + path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'ajax1.jsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

<script type="text/javascript">
    //创建异步对象
    function createXMLHttpRequest() {
        try {
            return new XMLHttpRequest();
        } catch (e) {
            try {
                return new ActiveXObject("Msxml2.XMLHTTP");
            } catch (e) {
                try {
                    return new ActiveXObject("Microsoft.XMLHTTP");
                } catch (e) {
                    alert("不晓得你用的什么浏览器!");
                    throw e;
                }
            }
        }
    }

    window.onload = function() {//文档加载完毕后执行
        var btn = document.getElementById("btn");
        btn.onclick = function() {//给按钮的点击事件注册监听
            /*
                ajax四步操作,得到服务器的响应
                把响应结果显示到h1元素中
             */
            //1.得到异步对象
            var xmlHttp = createXMLHttpRequest();
            //2.打开与服务器 的连接
            xmlHttp.open("GET", "/day23_1/AServlet", true);
            //3.发送请求
            xmlHttp.send(null);
            //4.给异步对象的ontreadystatechange事件注册监听器
            xmlHttp.onreadystatechange = function() {//当xmlHttp的状态发生变化时执行
                if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                    //获取服务器的响应内容
                    var text = xmlHttp.responseText;
                    //获取h1元素
                    var h1 = document.getElementById("h1");
                    h1.innerHTML = text;
                }
            };
        };
    };
</script>

</head>

<body>
    <button id="btn">点击这里</button>
    <h1 id="h1"></h1>
</body>
</html>

第二例:发生POST请求(如果发送请求时需要带有参数,一般都用POST请求)

  *open:xmlHttp.open("POST", ....);

  *添加一步:设置Content-Type请求头:

    > xmlHttp.setRequestHeader("Content-Type",  "application/x-www-form-urlencoded");

  *send:xmlHttp.send("username=zhangSan&password=123");//发送请求时指定请求体

 AServlet:

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=utf-8");
        String username = request.getParameter("username");
        
        System.out.println("(POST)Hello AJAX! "+username);
        
        response.getWriter().print(username);
    }

ajax2.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://"
            + request.getServerName() + ":" + request.getServerPort()
            + path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'ajax1.jsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

<script type="text/javascript">
    //创建异步对象
    function createXMLHttpRequest() {
        try {
            return new XMLHttpRequest();
        } catch (e) {
            try {
                return new ActiveXObject("Msxml2.XMLHTTP");
            } catch (e) {
                try {
                    return new ActiveXObject("Microsoft.XMLHTTP");
                } catch (e) {
                    alert("不晓得你用的什么浏览器!");
                    throw e;
                }
            }
        }
    }

    window.onload = function() {//文档加载完毕后执行
        var btn = document.getElementById("btn");
        btn.onclick = function() {//给按钮的点击事件注册监听
            /*
                ajax四步操作,得到服务器的响应
                把响应结果显示到h1元素中
             */
            //1.得到异步对象
            var xmlHttp = createXMLHttpRequest();
            //2.打开与服务器 的连接
            /*****************修改open方法,指定请求方式为POST*******************/
            xmlHttp.open("POST", "<c:url value='/AServlet'/>", true);
            /********设置请求头:Content-Type*********/
            xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            
            //3.发送请求
            /************发送时指定请求体*************/
            xmlHttp.send("username=金泰妍");//GET请求没有请求体,但也要给出null,不然FireFox可能会不能发送!
            //4.给异步对象的ontreadystatechange事件注册监听器
            xmlHttp.onreadystatechange = function() {//当xmlHttp的状态发生变化时执行
                if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                    //获取服务器的响应内容
                    var text = xmlHttp.responseText;
                    //获取h1元素
                    var h1 = document.getElementById("h1");
                    h1.innerHTML = text;
                }
            };
        };
    };
</script>

</head>

<body>
    <button id="btn">点击这里</button>
    <h1 id="h1"></h1>
</body>
</html>

第三例:注册表单之校验用户是否注册!

1.编写页面:

  * ajax3.jsp

    >给出注册表单页面

    >给用户名文本框添加onblur事件的监听

    >获取文本框的内容,通过ajax 4步发送给服务器,得到响应结果

      * 如果为1:在文本框后面显示 “用户名已被注册” 

      * 如果为0:什么都不做!

2.编写Servlet

  * ValidateUsernameServlet

    > 获取客户端传递的用户名参数

    > 判断是否为itcast

      * 是:返回1

      * 否:返回0

 ValidateUsernameServlet.java:

package com.xjs.web.servlet;

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

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ValidateUsernameServlet extends HttpServlet {

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=utf-8");
        request.setCharacterEncoding("UTF-8");

        /*
         * 1.获取参数username 2.判断是否为itcast 3.是:响应1 4.否:响应0
         */
        String username = request.getParameter("username");
        System.out.println(username);
        if (username.equalsIgnoreCase("itcast")) {
            System.out.println("1");
            response.getWriter().print("1");
        } else {
            System.out.println("0");
            response.getWriter().print("0");
        }
    }
}

 

ajax3.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://"
            + request.getServerName() + ":" + request.getServerPort()
            + path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'ajax3.jsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

<script type="text/javascript">
    //创建异步对象
    function createXMLHttpRequest() {
        try {
            return new XMLHttpRequest();
        } catch (e) {
            try {
                return new ActiveXObject("Msxml2.XMLHTTP");
            } catch (e) {
                try {
                    return new ActiveXObject("Microsoft.XMLHTTP");
                } catch (e) {
                    alert("不晓得你用的什么浏览器!");
                    throw e;
                }
            }
        }
    }

    window.onload = function() {
        //获取文本框,给它的失去焦点事件注册监听
        var userEle = document.getElementById("usernameEle");
        userEle.onblur = function() {
            //1.得到异步对象    
            var xmlHttp = createXMLHttpRequest();
            //2.打开连接
            xmlHttp.open("POST", "<c:url value='/ValidateUsernameServlet'/>",
                    true);
            //3.设置请求头:Content-Type
            xmlHttp.setRequestHeader("Content-Type",
                    "application/x-www-form-urlencoded");
            //4.发送请求,给出请求体
            xmlHttp.send("username=" + userEle.value);
            //5.给xmlHttp的onreadystatechange事件注册监听
            xmlHttp.onreadystatechange = function() {
                if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                    //获取服务器的响应,判断是否为1
                    //是:获取span,添加内容:“用户名已被注册”;
                    var text = xmlHttp.responseText;
                    var span = document.getElementById("errorSpan");
                    if (text == "1") {
                        //得到span元素
                        span.innerHTML = "用户名已被注册!";
                    } else {
                        span.innerHTML = "";
                    }
                }
            };
        };
    };
</script>

</head>

<body>
    <h1>演示用户名是否已被注册</h1>
    <form action="" method="post">
        用户名:<input type="text" name="username" id="usernameEle" /><span id="errorSpan"></span><br> 
            密码:<input type="password" name="password" /><br> 
            <input type="submit" value="注册" />
    </form>
</body>
</html>

 


 

第四例: 响应内容为xml数据

  * 服务器端:

    > 设置响应头:Content-Type,其值为:text/xml; charset=utf-8

   * 客户端:

    > var doc = xmlHttp.responseXML;  //得到的是Document对象!

BServlet:

package com.xjs.web.servlet;

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

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class BServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/xml;charset=utf-8");
        String xml="<students>"+
                "<student number='ITCAST_1001'>"+
                "<name>金泰妍</name>"+
                "<age>23</age>"+
                "<sex>女</sex>"+
                "</student>"+
                "</students>";
        response.getWriter().print(xml);
    }
}

 ajax4.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://"
            + request.getServerName() + ":" + request.getServerPort()
            + path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'ajax1.jsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

<script type="text/javascript">
    //创建异步对象
    function createXMLHttpRequest() {
        try {
            return new XMLHttpRequest();
        } catch (e) {
            try {
                return new ActiveXObject("Msxml2.XMLHTTP");
            } catch (e) {
                try {
                    return new ActiveXObject("Microsoft.XMLHTTP");
                } catch (e) {
                    alert("不晓得你用的什么浏览器!");
                    throw e;
                }
            }
        }
    }

    window.onload = function() {//文档加载完毕后执行
        var btn = document.getElementById("btn");
        btn.onclick = function() {//给按钮的点击事件注册监听
            /*
                ajax四步操作,得到服务器的响应
                把响应结果显示到h1元素中
             */
            //1.得到异步对象
            var xmlHttp = createXMLHttpRequest();
            //2.打开与服务器 的连接
            xmlHttp.open("GET", "/day23_1/BServlet", true);
            //3.发送请求
            xmlHttp.send(null);
            //4.给异步对象的ontreadystatechange事件注册监听器
            xmlHttp.onreadystatechange = function() {//当xmlHttp的状态发生变化时执行
                if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                    //获取服务器的响应内容(XML)
                    var doc = xmlHttp.responseXML;
                    //查询文档下名为student的所有元素,得到数组,再取下标0元素
                    var ele = doc.getElementsByTagName("student")[0];
                    var number=ele.getAttribute("number");//获取元素名为number的属性值
                    var name=ele.getElementsByTagName("name")[0].textContent;//IE支持
                    var age=ele.getElementsByTagName("age")[0].textContent;
                    var sex=ele.getElementsByTagName("sex")[0].textContent;
                    var text=number+","+name+","+age+","+sex;
                    document.getElementById("h1").innerHTML=text;
                }
            };
        };
    };
</script>

</head>

<body>
    <button id="btn">点击这里</button>
    <h1 id="h1"></h1>
</body>
</html>

 第五例:省市联动

1.页面

  <select name="province">

    <option>===请选择省份===</option>

  </select>

  <select name="city">

    <option>===请选择城市===</option>

  </select>

2.ProvinceServlet

  * ProvinceServlet:当页面加载完毕后马上请求这个Servlet!

    > 它需要加载china.xml文件,把所有的省的名称使用字符串发送给客户端!

 3.页面的工作

  * 获取这个字符串,使用逗号分隔,得到数组

  * 循环遍历每个字符串(省份的名称),使用每个字符串创建一个<option>元素添加到<select name="province">这个元素中

4.CityServlet

  * CityServlet:当页面选择某个省时,发送请求!

  * 得到省份的名称,加载china.xml文件,查询出该省份对应的元素对象!把这个元素转换成xml字符串,发送给客户端

5.页面的工作

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

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

  * 获取所有的<city>子元素,循环遍历,得到<city>的内容

  * 使用每个<city>的内容创建一个<option>元素,添加到<select name="city">

 省份在src下的china.xml:

<?xml version="1.0" encoding="utf-8"?>
<china>
    <province name="北京">
        <city>东城区</city>
        <city>西城区</city>
        <city>崇文区</city>
        <city>宣武区</city>
        <city>朝阳区</city>
        <city>丰台区</city>
        <city>石景山区</city>
        <city>海淀区</city>
        <city>门头沟区</city>
        <city>房山区</city>
        <city>通州区</city>
        <city>顺义区</city>
        <city>昌平区</city>
        <city>大兴区</city>
        <city>怀柔区</city>
        <city>平谷区</city>
        <city>密云县</city>
        <city>延庆县</city>
    </province>
    <province name="天津">
        <city>和平区</city>
        <city>河东区</city>
        <city>河西区</city>
        <city>南开区</city>
        <city>河北区</city>
        <city>红桥区</city>
        <city>塘沽区</city>
        <city>汉沽区</city>
        <city>大港区</city>
        <city>东丽区</city>
        <city>西青区</city>
        <city>津南区</city>
        <city>北辰区</city>
        <city>武清区</city>
        <city>宝坻区</city>
        <city>宁河县</city>
        <city>静海县</city>
        <city>蓟县</city>
    </province>
    <province name="河北">
        <city>石家庄</city>
        <city>唐山</city>
        <city>秦皇岛</city>
        <city>邯郸</city>
        <city>邢台</city>
        <city>保定</city>
        <city>张家口</city>
        <city>承德</city>
        <city>沧州</city>
        <city>廊坊</city>
        <city>衡水</city>
    </province>
    <province name="山西">
        <city>太原</city>
        <city>大同</city>
        <city>阳泉</city>
        <city>长治</city>
        <city>晋城</city>
        <city>朔州</city>
        <city>晋中</city>
        <city>运城</city>
        <city>忻州</city>
        <city>临汾</city>
        <city>吕梁</city>
    </province>
    <province name="内蒙古">
        <city>呼和浩特</city>
        <city>包头</city>
        <city>乌海</city>
        <city>赤峰</city>
        <city>通辽</city>
        <city>鄂尔多斯</city>
        <city>呼伦贝尔</city>
        <city>巴彦淖尔</city>
        <city>乌兰察布</city>
        <city>兴安盟</city>
        <city>锡林郭勒盟</city>
        <city>阿拉善盟</city>
    </province>
    <province name="辽宁">
        <city>沈阳</city>
        <city>大连</city>
        <city>鞍山</city>
        <city>抚顺</city>
        <city>本溪</city>
        <city>丹东</city>
        <city>锦州</city>
        <city>营口</city>
        <city>阜新</city>
        <city>辽阳</city>
        <city>盘锦</city>
        <city>铁岭</city>
        <city>朝阳</city>
        <city>葫芦岛</city>
    </province>
    <province name="吉林">
        <city>长春</city>
        <city>吉林</city>
        <city>四平</city>
        <city>辽源</city>
        <city>通化</city>
        <city>白山</city>
        <city>松原</city>
        <city>白城</city>
        <city>延边</city>
    </province>
    <province name="黑龙江">
        <city>哈尔滨</city>
        <city>齐齐哈尔</city>
        <city>鸡西</city>
        <city>鹤岗</city>
        <city>双鸭山</city>
        <city>大庆</city>
        <city>伊春</city>
        <city>佳木斯</city>
        <city>七台河</city>
        <city>牡丹江</city>
        <city>黑河</city>
        <city>绥化</city>
        <city>大兴安岭</city>
    </province>
    <province name="上海">
        <city>黄浦区</city>
        <city>卢湾区</city>
        <city>徐汇区</city>
        <city>长宁区</city>
        <city>静安区</city>
        <city>普陀区</city>
        <city>闸北区</city>
        <city>虹口区</city>
        <city>杨浦区</city>
        <city>闵行区</city>
        <city>宝山区</city>
        <city>嘉定区</city>
        <city>浦东新区</city>
        <city>金山区</city>
        <city>松江区</city>
        <city>青浦区</city>
        <city>南汇区</city>
        <city>奉贤区</city>
        <city>崇明县</city>
    </province>
    <province name="江苏">
        <city>南京</city>
        <city>无锡</city>
        <city>徐州</city>
        <city>常州</city>
        <city>苏州</city>
        <city>南通</city>
        <city>连云港</city>
        <city>淮安</city>
        <city>盐城</city>
        <city>扬州</city>
        <city>镇江</city>
        <city>泰州</city>
        <city>宿迁</city>
    </province>
    <province name="浙江">
        <city>杭州</city>
        <city>宁波</city>
        <city>温州</city>
        <city>嘉兴</city>
        <city>湖州</city>
        <city>绍兴</city>
        <city>金华</city>
        <city>衢州</city>
        <city>舟山</city>
        <city>台州</city>
        <city>丽水</city>
    </province>
    <province name="安徽">
        <city>合肥</city>
        <city>芜湖</city>
        <city>蚌埠</city>
        <city>淮南</city>
        <city>马鞍山</city>
        <city>淮北</city>
        <city>铜陵</city>
        <city>安庆</city>
        <city>黄山</city>
        <city>滁州</city>
        <city>阜阳</city>
        <city>宿州</city>
        <city>巢湖</city>
        <city>六安</city>
        <city>亳州</city>
        <city>池州</city>
        <city>宣城</city>
    </province>
    <province name="福建">
        <city>福州</city>
        <city>厦门</city>
        <city>莆田</city>
        <city>三明</city>
        <city>泉州</city>
        <city>漳州</city>
        <city>南平</city>
        <city>龙岩</city>
        <city>宁德</city>
    </province>
    <province name="江西">
        <city>南昌</city>
        <city>景德镇</city>
        <city>萍乡</city>
        <city>九江</city>
        <city>新余</city>
        <city>鹰潭</city>
        <city>赣州</city>
        <city>吉安</city>
        <city>宜春</city>
        <city>抚州</city>
        <city>上饶</city>
    </province>
    <province name="山东">
        <city>济南</city>
        <city>青岛</city>
        <city>淄博</city>
        <city>枣庄</city>
        <city>东营</city>
        <city>烟台</city>
        <city>潍坊</city>
        <city>济宁</city>
        <city>泰安</city>
        <city>威海</city>
        <city>日照</city>
        <city>莱芜</city>
        <city>临沂</city>
        <city>德州</city>
        <city>聊城</city>
        <city>滨州</city>
        <city>荷泽</city>
    </province>
    <province name="河南">
        <city>郑州</city>
        <city>开封</city>
        <city>洛阳</city>
        <city>平顶山</city>
        <city>安阳</city>
        <city>鹤壁</city>
        <city>新乡</city>
        <city>焦作</city>
        <city>濮阳</city>
        <city>许昌</city>
        <city>漯河</city>
        <city>三门峡</city>
        <city>南阳</city>
        <city>商丘</city>
        <city>信阳</city>
        <city>周口</city>
        <city>驻马店</city>
    </province>
    <province name="湖北">
        <city>武汉</city>
        <city>黄石</city>
        <city>十堰</city>
        <city>宜昌</city>
        <city>襄樊</city>
        <city>鄂州</city>
        <city>荆门</city>
        <city>孝感</city>
        <city>荆州</city>
        <city>黄冈</city>
        <city>咸宁</city>
        <city>随州</city>
        <city>恩施</city>
        <city>神农架</city>
    </province>
    <province name="湖南">
        <city>长沙</city>
        <city>株洲</city>
        <city>湘潭</city>
        <city>衡阳</city>
        <city>邵阳</city>
        <city>岳阳</city>
        <city>常德</city>
        <city>张家界</city>
        <city>益阳</city>
        <city>郴州</city>
        <city>永州</city>
        <city>怀化</city>
        <city>娄底</city>
        <city>湘西</city>
    </province>
    <province name="广东">
        <city>广州</city>
        <city>韶关</city>
        <city>深圳</city>
        <city>珠海</city>
        <city>汕头</city>
        <city>佛山</city>
        <city>江门</city>
        <city>湛江</city>
        <city>茂名</city>
        <city>肇庆</city>
        <city>惠州</city>
        <city>梅州</city>
        <city>汕尾</city>
        <city>河源</city>
        <city>阳江</city>
        <city>清远</city>
        <city>东莞</city>
        <city>中山</city>
        <city>潮州</city>
        <city>揭阳</city>
        <city>云浮</city>
    </province>
    <province name="广西">
        <city>南宁</city>
        <city>柳州</city>
        <city>桂林</city>
        <city>梧州</city>
        <city>北海</city>
        <city>防城港</city>
        <city>钦州</city>
        <city>贵港</city>
        <city>玉林</city>
        <city>百色</city>
        <city>贺州</city>
        <city>河池</city>
        <city>来宾</city>
        <city>崇左</city>
    </province>
    <province name="海南">
        <city>海口</city>
        <city>三亚</city>
    </province>
    <province name="重庆">
        <city>重庆</city>
        <city>万州区</city>
        <city>涪陵区</city>
        <city>渝中区</city>
        <city>大渡口区</city>
        <city>江北区</city>
        <city>沙坪坝区</city>
        <city>九龙坡区</city>
        <city>南岸区</city>
        <city>北碚区</city>
        <city>万盛区</city>
        <city>双桥区</city>
        <city>渝北区</city>
        <city>巴南区</city>
        <city>黔江区</city>
        <city>长寿区</city>
        <city>綦江县</city>
        <city>潼南县</city>
        <city>铜梁县</city>
        <city>大足县</city>
        <city>荣昌县</city>
        <city>璧山县</city>
        <city>梁平县</city>
        <city>城口县</city>
        <city>丰都县</city>
        <city>垫江县</city>
        <city>武隆县</city>
        <city>忠县</city>
        <city>开县</city>
        <city>云阳县</city>
        <city>奉节县</city>
        <city>巫山县</city>
        <city>巫溪县</city>
        <city>石柱土家族自治县</city>
        <city>秀山土家族苗族自治县</city>
        <city>酉阳土家族苗族自治县</city>
        <city>彭水苗族土家族自治县</city>
        <city>江津</city>
        <city>合川</city>
        <city>永川</city>
        <city>南川</city>
    </province>
    <province name="四川">
        <city>成都</city>
        <city>自贡</city>
        <city>攀枝花</city>
        <city>泸州</city>
        <city>德阳</city>
        <city>绵阳</city>
        <city>广元</city>
        <city>遂宁</city>
        <city>内江</city>
        <city>乐山</city>
        <city>南充</city>
        <city>眉山</city>
        <city>宜宾</city>
        <city>广安</city>
        <city>达州</city>
        <city>雅安</city>
        <city>巴中</city>
        <city>资阳</city>
        <city>阿坝</city>
        <city>甘孜</city>
        <city>凉山</city>
    </province>
    <province name="贵州">
        <city>贵阳</city>
        <city>六盘水</city>
        <city>遵义</city>
        <city>安顺</city>
        <city>铜仁</city>
        <city>黔西南</city>
        <city>毕节</city>
        <city>黔东南</city>
        <city>黔南</city>
    </province>
    <province name="云南">
        <city>昆明</city>
        <city>曲靖</city>
        <city>玉溪</city>
        <city>保山</city>
        <city>昭通</city>
        <city>丽江</city>
        <city>思茅</city>
        <city>临沧</city>
        <city>楚雄</city>
        <city>红河</city>
        <city>文山</city>
        <city>西双版纳</city>
        <city>大理</city>
        <city>德宏</city>
        <city>怒江</city>
        <city>迪庆</city>
    </province>
    <province name="西藏">
        <city>拉萨</city>
        <city>昌都</city>
        <city>山南</city>
        <city>日喀则</city>
        <city>那曲</city>
        <city>阿里</city>
        <city>林芝</city>
    </province>
    <province name="陕西">
        <city>西安</city>
        <city>铜川</city>
        <city>宝鸡</city>
        <city>咸阳</city>
        <city>渭南</city>
        <city>延安</city>
        <city>汉中</city>
        <city>榆林</city>
        <city>安康</city>
        <city>商洛</city>
    </province>
    <province name="甘肃">
        <city>兰州</city>
        <city>嘉峪关</city>
        <city>金昌</city>
        <city>白银</city>
        <city>天水</city>
        <city>武威</city>
        <city>张掖</city>
        <city>平凉</city>
        <city>酒泉</city>
        <city>庆阳</city>
        <city>定西</city>
        <city>陇南</city>
        <city>临夏</city>
        <city>甘南</city>
    </province>
    <province name="青海">
        <city>西宁</city>
        <city>海东</city>
        <city>海北</city>
        <city>黄南</city>
        <city>海南</city>
        <city>果洛</city>
        <city>玉树</city>
        <city>海西</city>
    </province>
    <province name="宁夏">
        <city>银川</city>
        <city>石嘴山</city>
        <city>吴忠</city>
        <city>固原</city>
        <city>中卫</city>
    </province>
    <province name="新疆">
        <city>乌鲁木齐</city>
        <city>克拉玛依</city>
        <city>吐鲁番</city>
        <city>哈密</city>
        <city>昌吉</city>
        <city>博尔塔拉</city>
        <city>巴音郭楞</city>
        <city>阿克苏</city>
        <city>克孜勒苏</city>
        <city>喀什</city>
        <city>和田</city>
        <city>伊犁</city>
        <city>塔城</city>
        <city>阿勒泰</city>
        <city>石河子</city>
        <city>阿拉尔</city>
        <city>图木舒克</city>
        <city>五家渠</city>
    </province>
    <province name="香港">
        <city>香港</city>
    </province>
    <province name="澳门">
        <city>澳门</city>
    </province>
    <province name="台湾">
        <city>台湾</city>
    </province>
</china>

 

ProvinceServlet:负责向页面响应所有的省份

 

package com.xjs.web.servlet;

import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;

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 ProvinceServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /*
         * 响应所有省份名称,使用逗号隔开!
         */
        /*
         * 1.Document对象
         *     》创建解析器对象
         *     》调用解析器的读方法,传递一个流对象,得到Document
         */
        StringBuilder str=new StringBuilder();
        SAXReader reader=new SAXReader();
        InputStream in=this.getClass().getResourceAsStream("/china.xml");
        Document doc;
        try {
            doc = reader.read(in);
        } catch (DocumentException e) {
            throw new RuntimeException(e);
        }

        Element root = doc.getRootElement();//根节点
        Iterator<Element> ele = root.elementIterator();
        while(ele.hasNext()){
            //每个省份
            Element province = ele.next();
            //得到省份的名称--即该节点的属性值
            String provinceName = province.attributeValue("name");
            if(ele.hasNext()){
                str=str.append(provinceName+",");
            }else{
                str=str.append(provinceName);
            }
        }
//        System.out.println(str);在控制台显示所有的省份,省份
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().print(str);
    }
}

 

北京,天津,河北,山西,内蒙古,辽宁,吉林,黑龙江,上海,江苏,浙江,安徽,福建,江西,山东,河南,湖北,湖南,广东,广西,海南,重庆,四川,贵州,云南,西藏,陕西,甘肃,青海,宁夏,新疆,香港,澳门,台湾

 CityServlet:根据选择的省份,去解析XML文件,找到该省的节点,直接使用asXML()转换成字符串,响应给页面

package com.xjs.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 {
        response.setContentType("text/xml;charset=utf-8");
        request.setCharacterEncoding("utf-8");
        /*
         * 获取省份名称,加载该省对应的<province>元素
         * 把元素转换成字符串发送给客户端
         */
        /*
         * 1.获取省份的名称
         * 2.使用省份名称查找到对应的<province>元素
         * 3.把<province>元素转换成字符串,发送!
         */
        SAXReader reader=new SAXReader();
        InputStream in=this.getClass().getResourceAsStream("/china.xml");
        Document doc;
        try {
            doc = reader.read(in);
        } catch (DocumentException e) {
            throw new RuntimeException(e);
        }
        //获取参数
        String pname = request.getParameter("pname");
        //根据条件查节点元素
        Element proEle=(Element) doc.selectSingleNode("//province[@name='"+pname+"']");
        String xmlStr = proEle.asXML();//把元素转换成字符串
//        System.out.println(xmlStr);在控制台显示该省中的市(XML格式)
        response.getWriter().print(xmlStr);
    }

}

 

      <province name="山东">
		<city>济南</city>
		<city>青岛</city>
		<city>淄博</city>
		<city>枣庄</city>
		<city>东营</city>
		<city>烟台</city>
		<city>潍坊</city>
		<city>济宁</city>
		<city>泰安</city>
		<city>威海</city>
		<city>日照</city>
		<city>莱芜</city>
		<city>临沂</city>
		<city>德州</city>
		<city>聊城</city>
		<city>滨州</city>
		<city>荷泽</city>
	</province>    

  ajax5.jsp:负责显示页面,处理异步请求

    1)请求ProvinceServlet,响应的文本信息,分隔得到数组,然后再添加option元素到select中

    2)根据选择的省,去请求CityServlet,响应的是XML信息,直接得到Document对象,然后再去增option元素,

      注意:2)中的首先要移除select中的option(除<option>===请选择市===</option>)元素,以免option元素的累加

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
			+ request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'ajax5.jsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

<script type="text/javascript">
	//创建异步对象
	function createXMLHttpRequest() {
		try {
			return new XMLHttpRequest();
		} catch (e) {
			try {
				return new ActiveXObject("Msxml2.XMLHTTP");
			} catch (e) {
				try {
					return new ActiveXObject("Microsoft.XMLHTTP");
				} catch (e) {
					alert("不晓得你用的什么浏览器!");
					throw e;
				}
			}
		}
	}

	/*
	 *	1.在文档加载完毕时发送请求,得到所有省份名称,显示在<select name="porvince"/>中
	 *	2.在选择了新的省份时,发送请求(参数为省份的名称),得到xml文档,即<province>元素
	 *	3.解析xml文档,得到其中所有的<city>,再得到每个<city>元素的内容,即市名,使用市名生成<option>,插入到<select name="city">元素中
	 */
	window.onload = function() {
		/*
			ajax四步,请求ProvinceServlet,得到所有的省份名称
			使用每个省份名称创建一个<option>元素,添加到<select name="province">中
		 */
		var xmlHttp = createXMLHttpRequest();
		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 arr = text.split(",");
				//循环遍历每个省份名称,每个名称生成一个option对象,添加到<select>元素中
				for (var i = 0; i < arr.length; i++) {
					var op = document.createElement("option");//创建指定名称的元素
					op.value = arr[i];//设置op的实际值为当前的省份名称
					var textNode = document.createTextNode(arr[i]);//创建文本节点
					op.appendChild(textNode);//把文本子节点添加到op元素中,指定显示值

					document.getElementById("p").appendChild(op);
				}
			}
		};

		/*
			第二件事情:给<select name="province">添加改变监听器
			使用选择的省份名称请求CityServlet,得到<province>元素(xml元素)!!!
			获取<province>元素中所有的<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){
						citySelect.removeChild(optionEleList[1]);//总是删除1下标,因为1删除了,2就变成1了
					}
					
					
					var doc = xmlHttp.responseXML;
					//得到所有名为city的元素
					var cityEleList = doc.getElementsByTagName("city");
					//循环遍历每个city元素
					for (var i = 0; i < cityEleList.length; i++) {
						var cityEle = cityEleList[i];//得到每个city元素
						var cityName;
						//获取市名称
						if (window.addEventListener) {
							cityName = cityEle.textContent;
						} else {
							cityName = cityEle.text;//支持IE
						}
						//使用市名称创建option元素,添加到<select name="city">
						var op = document.createElement("option");
						op.value = cityName;
						//创建文本节点
						var textNode = document.createTextNode(cityName);
						op.appendChild(textNode);
						//把op添加到<select>中
						citySelect.appendChild(op);
					}
				}
			};
		};
	};
</script>

</head>

<body>
	<h1>省市联动</h1>
	<select name="porvince" id="p">
		<option>===请选择省===</option>
	</select>    
	<select name="porvince" id="c">
		<option>===请选择市===</option>
	</select>
</body>
</html>

  

 

posted @ 2019-06-12 10:36  微微亮  阅读(119)  评论(0编辑  收藏  举报