JavaWeb中Ajax的使用-基本使用+省市联动例子

本文主要是在JavaWeb中如何使用Ajax,是属于原生的使用方法,不涉及jQuery等知识,是直接利用JavaScript进行与Web服务器进行交互;

1、AJAX
2、AJAX基础实现与应用
3、AJAX省市联动实现与应用


1、AJAX(摘自百度百科文章)

  • 同步交互与异步交互
    • 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
    • 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。
  • 什么是AJAX
    AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和 XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。
    AJAX还有一个最大的特点就是,当服务器响应时,不用刷新整个浏览器页面,而是可以局部刷新。这一特点给用户的感受是在不知不觉中完成请求和响应过程。
  • 应用场景:
    • 与服务器异步交互;
    • 浏览器页面局部刷新;

2、AJAX基础实现与应用
ajax发送一步请求最基本的做法(最结为四个主要步骤):

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


1、第一步(得到XMLHttpRequest)
大多数浏览器都支持:var xmlHttp = new XMLHttpRequest();
IE6.0:var xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
IE5.5以更早版本的IE:var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");


创建 XMLHttpRequest对象的函数

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("无法识别使用的浏览器,AJAX可能失效");
              throw e;
          }
      }
      }
  }

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

  • xmlHttp.open():用来打开与服务器的连接,它需要三个参数:
    请求方式:可以是GET或POST
    请求的URL:指定服务器端资源,例如;/DemoAJAX/AServlet
    请求是否为异步:如果为true表示发送异步请求,否则同步请求!
    xmlHttp.open("GET", "/DemoAJAX/AServlet", true);

3、 第三步(发送请求)

  • 当使用open打开连接后,就可以调用XMLHttpRequest对象的send()方法发送请求了。
  • send()方法的参数为POST请求参数,即对应HTTP协议的请求体内容,若是GET请求,需要在URL后连接参数。
  • 若没有参数,需要给出null为参数!若不给出null为参数,可能会导致FireFox浏览器不能正常发送请求!
  • xmlHttp.send(null):如果不给可能会造成部份浏览器无法发送!

4、 第四步(接收服务器响应)

  • xmlHttp对象的一个事件上注册监听器:onreadystatechange
  • xmlHttp对象一共有5个状态:
N状态所处阶段执行
0状态刚创建只是创建了XMLHttpRequest对象,还未调用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 == 4 && xmlHttp.status == 200) {
                //双重判断:判断是否为4状态,而且还要判断是否为200
                 // 获取服务器的响应内容
                var text = xmlHttp.responseText;
            }
    };

1)AJAX第一例(GET请求)
首先创建一个JavaWeb工程,创建一个Servlet


  • AServlet.java
import java.io.IOException;

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

public class AServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        System.out.println("Ajax测试---Hello Ajax");
        response.getWriter().print("Ajax测试---Hello Ajax");
    }

}

  • demo1.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 'demo1.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() {
            var xmlHttp;
            try {
                return xmlHttp = new XMLHttpRequest();
            } catch (e) {
                 try {
                    return xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
                } catch (e) {
                    try {
                        return xmlHttp = new ActiveXObject("Micrsoft.XMLHTTP");
                    } catch (e) {
                        alter("无法识别您的浏览器,将会失去异步传输功能");
                        throw e;
                    }
                }
            }
        }

        window.onload = function() {
            var btn = document.getElementById("btn");
            btn.onclick = function() {
                //创建对象
                var xmlHttp = createXMLHttpRequest();
                //打开与服务器的连接
                xmlHttp.open("GET","<c:url value='/AServlet' />",true);
                //发送请求
                xmlHttp.send(null);
                //注册监听获取事件状态
                xmlHttp.onreadystatechange = function() {
                    if(xmlHttp.readyState == 4 && xmlHttp.status == 200){
                        var h1 = document.getElementById("h1");
                        h1.innerHTML = xmlHttp.responseText;
                    }
                };
            };  
        };
    </script>
  </head>
    <button id="btn">点击这里</button>
    <h1 id="h1"></h1>
  <body>

  </body>
</html>

2)AJAX第二例(POST请求)


  • BServlet.java
import java.io.IOException;

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

public class BServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    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("Ajax测试---POST方式:username="+username);
        response.getWriter().print("Ajax测试---POST方式:username="+username);
    }
}
  • demo2.jsp(只给出重要的js代码片段)
<script type="text/javascript">
        function createXMLHttpRequest() {
            var xmlHttp;
            try {
                return xmlHttp = new XMLHttpRequest();
            } catch (e) {
                 try {
                    return xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
                } catch (e) {
                    try {
                        return xmlHttp = new ActiveXObject("Micrsoft.XMLHTTP");
                    } catch (e) {
                        alter("无法识别您的浏览器,将会失去异步传输功能");
                        throw e;
                    }
                }
            }
        }

        window.onload = function() {
            var btn = document.getElementById("btn");
            btn.onclick = function() {
                //创建对象
                var xmlHttp = createXMLHttpRequest();
                //打开与服务器的连接
                xmlHttp.open("POST","<c:url value='/BServlet' />",true);
                xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
                //发送请求
                var username = document.getElementById("username").value;
                xmlHttp.send("username="+username);
                //注册监听获取事件状态
                xmlHttp.onreadystatechange = function() {
                    if(xmlHttp.readyState == 4 && xmlHttp.status == 200){
                        var h1 = document.getElementById("h1");
                        h1.innerHTML = xmlHttp.responseText;
                    }
                };
            };  
        };
    </script>
 
 
  • 1

3)AJAX省市联动的例子(省市数据来源一般可以使用XML文件进行存放或者使用数据库进行存放,在本例中使用了XML文件进行存放)

给出部分China.xml文件片段:

<?xml version="1.0" encoding="utf-8"?>
<china>
    <province name="北京">
        <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>
  • CityServlet.java
public class CityServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/xml;charset=UTF-8");
        /*
         * 1、获取省份的名称
         * 2、使用省份的名称,并且对于区域进行查找
         * 3、转换成字符串进行发送!
         */
        try{
            SAXReader reader = new SAXReader();//解析器
            InputStream input = this.getClass().getResourceAsStream("/china.xml");
            org.dom4j.Document doc = reader.read(input);
            /*
             * 获取参数
             */
            String pname = request.getParameter("pname");
            Element proEle = (Element) doc.selectSingleNode("//province[@name='"+pname+"']");
            String xmlStr = proEle.asXML();
            response.getWriter().print(xmlStr);
        } catch (Exception e) {
            // TODO: handle exception
            throw new RuntimeException(e);
        }
    }

}
  • ProvinceServlet.java
public class ProvinceServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @SuppressWarnings("unchecked")
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/xml;charset=UTF-8");
        /*
         * 1、Doument对象
         *   *创建解析器对象
         *   *调用解析器的读方法,传递一个流对象,得到Document
         */
        try{
            SAXReader reader = new SAXReader();//解析器
            InputStream input = this.getClass().getResourceAsStream("/china.xml");
            org.dom4j.Document doc = reader.read(input);
            System.out.println(doc);

            /*
             * 查询所有的province的name属性,得到一堆的属性对象
             */
            List<Attribute> arrList = doc.selectNodes("//province/@name");//@表示属性
            System.out.println(arrList);
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < arrList.size() ; i++) {
                sb.append(arrList.get(i).getValue());
                if (i < arrList.size() - 1) {
                    sb.append(",");
                }
            }
            response.getWriter().print(sb);
        } catch (Exception e) {
            // TODO: handle exception
            throw new RuntimeException(e);
        }
    }

    @Test
    public void demo() throws Exception {
        SAXReader reader = new SAXReader();//解析器
        InputStream input = this.getClass().getResourceAsStream("/china.xml");
        Document doc = reader.read(input);
        System.out.println(doc);
    }
}
  • 前端页面demo3.jsp(代码)
<html>
  <head>
    <title>My JSP 'demo3.jsp' starting page</title>
    <script type="text/javascript">
        function createXMLHttpRequest() {
            var xmlHttp;
            try {
                return xmlHttp = new XMLHttpRequest();
            } catch (e) {
                 try {
                    return xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
                } catch (e) {
                    try {
                        return xmlHttp = new ActiveXObject("Micrsoft.XMLHTTP");
                    } catch (e) {
                        alter("无法识别您的浏览器,将会失去异步传输功能");
                        throw e;
                    }
                }
            }
        }

        window.onload = function() {
            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(",");
                    for(var i = 0;i < arr.length;i++){
                        //创建指定名称的元素
                        var option = document.createElement("option");
                        option.value = arr[i];//设置实际的值
                        var textNode = document.createTextNode(arr[i]);//创建文本节点
                        option.appendChild(textNode);//添加文本子节点
                        document.getElementById("p").appendChild(option);
                    }
                }
            };
        };

        function selectCity(){
            var xmlHttp = createXMLHttpRequest();
            xmlHttp.open("POST","<c:url value='/CityServlet'/>",true);
            xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
            var pname = document.getElementById("p").value;
            xmlHttp.send("pname="+pname);
            xmlHttp.onreadystatechange = function() {
                if(xmlHttp.readyState == 4 && xmlHttp.status == 200){
                    var citySelect = document.getElementById("c");
                    var optionEleList = citySelect.getElementsByTagName("option");
                    while(optionEleList.length > 1){
                        citySelect.removeChild(optionEleList[1]);//总是删除第一个下标,因为删除1了下面的会顶上来
                    }
                    var doc = xmlHttp.responseXML;
                    var cityElementList = doc.getElementsByTagName("city");
                    for(var i=0;i<cityElementList.length;i++){
                        var cityElement = cityElementList[i];
                        var cityName;
                        if(window.addEventListener) {
                            cityName = cityElement.textContent;//支持火狐等浏览器
                        } else{
                            cityName = cityElement.text;//支持IE
                        }

                        var option = document.createElement("option");
                        option.value = cityName;
                        var textNode = document.createTextNode(cityName);
                        option.appendChild(textNode);
                        //定义在之前:var citySelect = document.getElementById("c");
                        citySelect.appendChild(option);
                    }
                }
            };
        }

    </script>
  </head>

  <body>
    <h1 id="h1"></h1>
    <h1>省市联动</h1>
    <select name="province" id="p" onchange="selectCity()">
        <option>===请选择省===</option>
    </select>
    &nbsp;&nbsp;&nbsp;&nbsp;
    <select name="city" id="c">
        <option>===请选择市===</option>
    </select>
  </body>
</html>
实现省市区三级联动的关键是建立好数据库,并且编写好对应的 SQL 语句。以下是一个简单的数据库设计: - 省份表 province,包括字段 id 和 name。 - 城市表 city,包括字段 id、name 和省份的外键 province_id。 - 区县表 district,包括字段 id、name 和城市的外键 city_id。 接下来是建表语句: ```sql -- 省份表 CREATE TABLE `province` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 城市表 CREATE TABLE `city` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL, `province_id` int(11) NOT NULL, PRIMARY KEY (`id`), KEY `province_id` (`province_id`), CONSTRAINT `city_ibfk_1` FOREIGN KEY (`province_id`) REFERENCES `province` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 区县表 CREATE TABLE `district` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL, `city_id` int(11) NOT NULL, PRIMARY KEY (`id`), KEY `city_id` (`city_id`), CONSTRAINT `district_ibfk_1` FOREIGN KEY (`city_id`) REFERENCES `city` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ``` 接下来是查询省份、城市、区县的 SQL 语句: ```sql -- 查询所有省份 SELECT id, name FROM province; -- 查询某个省份下的所有城市 SELECT id, name FROM city WHERE province_id = ?; -- 查询某个城市下的所有区县 SELECT id, name FROM district WHERE city_id = ?; ``` 在 Java Web 项目,可以使用 Ajax 和 JSON 技术实现省市区三级联动。前端页面发送 Ajax 请求,后端通过 JDBC 连接数据库,查询对应的省份、城市、区县信息,并以 JSON 格式返回给前端页面。前端页面再解析 JSON 数据,更新页面的省份、城市、区县下拉框选项。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值