AJAX

1、全局刷新和局部刷新

B/S 结构项目中, 浏览器(Browse)负责把用户的请求和参数通过网络发送给服务器(Server),服务端使用 Servlet(多种服务端技术的一种)接收请求,并将处理结果返回给浏览器。
浏览器在 html,jsp 上呈现数据,混合使用 css, js 帮助美化页面,或响应事件。

1.1 全局刷新

登录请求处理:
index.jsp 发起登录请求--------LoginServlet--------result.jsp

发起请求 request 阶段:

浏览器现在内存中是 index 页面的内容和数据 :

img

服务器端应答结果阶段:
sevlet 返回后把数据全部覆盖掉原来 index 页面内容, result.jsp 覆盖了全部的浏览器内存数据。 整个浏览器数据全部被刷新。重新在浏览器窗口显示数据,样式,标签等

img

全局刷新原理:

  1. 必须由浏览器亲自向服务端发送请求协议包。
  2. 这个行为导致服务端直接将【响应包】发送到浏览器内存中
  3. 这个行为导致浏览器内存中原有内容被覆盖掉
  4. 这个行为导致浏览器在展示数据时候,只有响应数据可以展示

1.2 局部刷新

浏览器在展示数据时,此时在窗口既可以看到本次的响应数据, 同时又可以看到浏览器内存中原有数据

局部刷新原理:

  1. 不能由浏览器发送请求给服务端
  2. 浏览器委托浏览器内存中一个脚本对象代替浏览器发送请求.
  3. 这个行为导致导致服务端直接将【响应包】发送脚本对象内存中
  4. 这个行为导致脚本对象内容被覆盖掉,但是此时浏览器内存中绝大部分内容没有收到任何影响.
  5. 这个行为导致浏览器在展示数据时候,同时展示原有数据和响应数据

img

AJAX 实现局部刷新的一种技术。

局部刷新使用的核心对象是 异步对象(XMLHttpRequest)

2、异步请求对象

在局部刷新,需要创建一个对象,代替浏览器发起请求的行为,这个对象存在内存中。代替浏览器发起请求并接收响应数据。这个对象叫做异步请求对象。全局刷新是同步行为, 局部刷新是异步行为[浏览器数据没有全部更新]

这个异步对象用于在后台与服务器交换数据。XMLHttpRequest 就是我们说的异步对象。
XMLHttpRequest 对象能够:

  • 在不重新加载页面的情况下更新网页
  • 在页面已加载后向服务器请求数据
  • 在页面已加载后从服务器接收数据

所有现代浏览器 (IE7+、Firefox、Chrome、Safari 以及 Opera) 都内建了 XMLHttpRequest 对象。

通过一行简单的 JavaScript 代码,我们就可以创建 XMLHttpRequest 对象。
创建 XMLHttpRequest 对象的语法(xhr):

var xmlhttp = new XMLHttpRequest();

AJAX 中的核心对象就是 XMLHttpRequest

3、AJAX

3.1 什么是 AJAX

AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。

  • AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分页面内容的新方法
  • AJAX 不是新的编程语言,而是使用现有技术混合使用的一种新方法。ajax 中使用的技术有JavaScript, html , dom , xml ,css 等。主要是 JavaScript , XML.
  • JavaScript: 使用脚本对象 XMLHttpRequest 发送请求, 接收响应数据
    XML: 发送和接收的数据格式,现在使用 json
  • AJAX 不单需要前端的技术,同时需要后端(服务器)的配合。服务器需要提供数据,数据是 AJAX 请求的响应结果。

3.2 AJAX 异步实现步骤

XMLHttpRequest 对象介绍

1. 创建对象方式

var xmlHttp = new XMLHttpRequest();

给异步对象绑定事件

当请求被发送到服务器时,我们需要执行一些基于响应的任务。每当 readyState 改变时,就会触发 onreadystatechange 事件。此事件可以指定一个处理函数 function。

通过判断 XMLHttpReqeust 对象的状态,获取服务端返回的数据。
语法:

xmlHttp.onreadystatechange= function() {
 if( xmlHttp.readyState == 4 && xmlHttp.status == 200){
 处理服务器返回数据
    }
 }

下面是 XMLHttpRequest 对象的三个重要的属性:
属性说明:
onreadystatechange 属性:一个 js 函数名 或 直接定义函数,每当 readyState 属性改变时,就会调用该函数
readyState 属性,存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。

  • 0: 请求未初始化,创建异步请求对象 var xmlHttp = new XMLHttpRequest()
  • 1: 初始化异步请求对象, xmlHttp.open(请求方式,请求地址,true)
  • 2: 异步对象发送请求, xmlHttp.send()
  • 3: 异步对象接收应答数据 从服务端返回数据。XMLHttpRequest 内部处理。
  • 4: 异步请求对象已经将数据解析完毕。 此时才可以读取数据。

status 属性:

  • 200: "OK"
  • 404: 未找到页面

2. 初始化异步请求对象参数

方法:

open(method,url,async) : 初始化异步请求对象

参数说明:
• method:请求的类型;GET 或 POST
• url:服务器的 servlet 地址
• async:true(异步)或 false(同步)
例如:

xmlHttp.open(“get”,”http:192.168.1.20:8080/myweb/query”,true)

3. 发送请求

xmlHttp.send()

4. 接收服务器响应的数据

如需获得来自服务器的响应,请使用 XMLHttpRequest 对象的 responseText 或responseXML 属性。

  • responseText:获得字符串形式的响应数据
  • responseXML:获得 XML 形式的响应数据

4、AJAX 实例

4.1 全局刷新计算 bmi

需求:计算某个用户的 BMI。 用户在 jsp 输入自己的身高,体重;servlet 中计算 BMI,并显示 BMI 的计算结果和建议。
BMI 指数(即身体质量指数,英文为 BodyMassIndex,简称 BMI),是用体重公斤数除以身高米数平方得出的数字,是目前国际上常用的衡量人体胖瘦程度以及是否健康的一个标准

成人的 BMI 数值:
1)过轻:低于 18.5
2)正常:18.5-23.9
3)过重:24-27
4)肥胖:28-32
5)非常肥胖,高于 32
开发步骤:

1. 在 idea 中创建新的工程

名称:ch01-bmi-ajax

img

2. 配置 tomcat 服务器

如果已经配置,省略此步骤。

img

选择 Local

img

配置 tomcat 服务器的位置

img

Module 添加 tomcat 支持

img

出现窗口

img

选择 2 Library

img

确定使用 tomcat

img

3. 创建 jsp

定义 form,有参数 name, weight, height

img

4. 创建 Servlet

名称 BMIServlet

public class BMIServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponseresp) throws ServletException, IOException {
        String strName = req.getParameter("name");
        String strWeight = req.getParameter("weight");
        String strHeight = req.getParameter("height");
        //计算 bmi
        float weight = Float.parseFloat(strWeight);
        float height = Float.parseFloat(strHeight);
        float bmi = weight / (height * height);
        System.out.println(String.format("%s 的 bmi%s",strName,bmi));
        String msg = "";
        if( bmi < 18.5 ){
            msg = "过瘦";
        } else if( bmi >= 18.5 && bmi < 23.9 ){
            msg = "正常";
        } else if( bmi >=23.9 && bmi <= 27){
            msg = "过重";
        } else if(bmi > 27 && bmi < 32 ){
            msg = "肥胖";
        } else {
            msg="非常肥胖";
        }
        // 把数据存入到request
        req.setAttribute("msg", strName + "你的 bmi 是"+ bmi+"," + msg);
        // 转发到新的页面
        req.getRequestDispatcher("/result.jsp").forward(req,resp);
    } 
}

5. 注册 servlet

<servlet>
	<servlet-name>Servlet模块名</servlet-name>
	<servlet-class>com.XXX.controller(包名).Servlet模块名</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>Servlet模块名</servlet-name>
    <url-pattern>/路径访问地址</url-pattern>
</servlet-mapping>

img

6. 创建 result.jsp

img

web 目录下创建 result.jsp 文件

7. 配置运行程序

输入参数。显示 bmi

4.2 使用 HttpServletResponse 响应输出

1. 新建 jsp

indexPrint.jsp

img

2. 新建 Servlet

名称 BMIServeltPrint

public class BmiAjaxServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request,HttpServletResponse response)
            throws ServletException, IOException {
       
    }

    protected void doGet(HttpServletRequest request,
                         HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("====接收了ajax的请求=====");

        //接收参数
        String strName = request.getParameter("name");
        String weight  = request.getParameter("w");
        String height = request.getParameter("h");

        //计算bmi
        float h = Float.valueOf(height);
        float w = Float.valueOf(weight);
        float bmi = w / ( h * h);

        //判断bmi的范围
        String msg = "";
        if( bmi <= 18.5) {
            msg = "您比较瘦";
        } else if( bmi > 18.5 && bmi <= 23.9 ){
            msg = "你的bmi是正常的";
        } else if( bmi >24 && bmi <=27){
            msg = "你的身体比较胖";
        } else {
            msg = "你的身体肥胖";
        }
        System.out.println("msg="+msg);
        msg = "您好:"+strName + "先生/女士, 您的bmi值是:"+ bmi + ","+ msg;

        //响应ajax需要的数据,使用HttpServletResponse输出数据
        response.setContentType("text/html;charset=utf-8");
        
        PrintWriter pw = response.getWriter();
        pw.println(msg);
        pw.flush();
        pw.close();
    }
}

3. 注册 Servlet

img

4.3 使用 ajax 请求,计算 bmi

1. 新建 ajax.jsp

img

2. 在 ajax.jsp 的 head 部分指定 doAjax()函数

<!-- 写在head中 -->
<script type="text/javascript">
	// 使用内存中的异步对象,代替浏览器发起请求。异步对象是使用js创建和管理的。

	function doAjax(){
	// 1.创建异步对象
	var xmlHttp = new XMLHttpRequest();

	// 2.绑定事件
	xmlHttp.onreadystatechange = function (){
		// 处理服务器端返回的数据,更新当前页面
		// alert("readyState属性值====" + xmlHttp.readyState + "  |  status:" + xmlHttp.status);
		if( xmlHttp.readyState == 4 && xmlHttp.status==200 ){
			alert(xmlHttp.responseText);
		}
	}

	// 3.初始请求数据
	xmlHttp.open("get","bmiAjax",true);

    // 4.发起请求
	xmlHttp.send();
}
</script>

3. 复制 BMIServletPrint,重新命名 BMIServletAjax

代码不需要改动

4. 注册 Servlet

img

5. 在浏览器访问 ajax.jsp

在 BMIServltAjax 的第一行设置断点,然后在 jsp 中点击按钮,发起请求,观察浏览器中的弹出的内容变化

6. 修改 ajax.jsp 中的 doAjax()函数

<script type="text/javascript">
    function doAjax() {
    //创建异步对象 
    var xmlHttp = new XMLHttpRequest();
    //绑定事件 
    xmlHttp.onreadystatechange = function () {
       alert( "处理请求的状态:" + xmlHttp.readyState + "|服务器端返回数据:"+xmlHttp.responseText);
    }
    //初始化参数 
    xmlHttp.open("get","bmiAjax?name=张三&height=1.8&weight=75",true);
    //发送 ajax 异步请求
    xmlHttp.send();
 }
</script>

7. 访问 ajax.jsp 请求

在 jsp 中点击按钮,发起请求,观察浏览器中的弹出的内容变化

8. 获取 dom 对象 value 值

<script type="text/javascript">
     function doAjax() {
       //创建异步对象 
       var xmlHttp = new XMLHttpRequest();
       //绑定事件 
       xmlHttp.onreadystatechange = function () {
          alert( "处理请求的状态:" + xmlHttp.readyState + "|服务器端返回数据:"+xmlHttp.responseText);
       }
       //初始化参数 
       //获取页面 dom 中的数据 
       var name = document.getElementById("name").value;
       var height = document.getElementById("height").value;
       var weight = document.getElementById("weight").value;
       var param = "name="+name+"&height="+height+"&weight="+weight;
       xmlHttp.open("get","bmiAjax?"+param,true);
       //发送 ajax 异步请求 
       xmlHttp.send();
 }
</script>

9. 在浏览器测试发送 ajax 请求

10. 修改 doAjax 函数

最后的jsp页面为

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>我的局部刷新测试-Ajax练习</title>

    <script type="text/javascript">
      // 使用内存中的异步对象,代替浏览器发起请求。异步对象是使用js创建和管理的。

      function doAjax(){
        // 1.创建异步对象
        var xmlHttp = new XMLHttpRequest();

        // 2.绑定事件
        xmlHttp.onreadystatechange = function (){
          // 处理服务器端返回的数据,更新当前页面
          if( xmlHttp.readyState == 4 && xmlHttp.status == 200 ) {
            var data = xmlHttp.responseText;
            // 更新dom对象,更新页面数据
            document.getElementById("mydata").innerText = data;
          }
        }

        // 3.初始请求数据

        // 获取dom对象的value属性值
        var name = document.getElementById("name").value;
        var weight = document.getElementById("weight").value;
        var height = document.getElementById("height").value;

        // bmiPrintServlet?name=张三&weight=100&height=1.85
        var param = "name=" + name + "&weight=" + weight +  "&height=" + height;

        xmlHttp.open("get","myBmiAjaxServlet?" + param,true);

        // 4.发起请求
        xmlHttp.send();
      }
    </script>
  </head>

  <body>
  <p>局部刷新-Ajax-计算BMI</p>
      <div>
        姓名:<input type="text" id="name"/><br/>
        体重(公斤):<input type="text" id="weight"/><br/>
        身高(米):<input type="text" id="height"/><br/>
        <input type="button" value="计算BMI" onclick="doAjax()">
        <br/> <br/>
        <div id = "mydata">
          等待加载数据......
        </div>
      </div>
  </body>

</html><script type="text/javascript">
 function doAjax() {
    //创建异步对象 
    var xmlHttp = new XMLHttpRequest();
    //绑定事件 
    xmlHttp.onreadystatechange = function () {
        if( xmlHttp.readyState == 4 && xmlHttp.status == 200){
            var data = xmlHttp.responseText
            document.getElementById("dataDiv").innerText = data;
        }
     }
    //初始化参数 
    //获取页面 dom 中的数据 
    var name = document.getElementById("name").value;
    var height = document.getElementById("height").value;
    var weight = document.getElementById("weight").value;
    var param = "name="+name+"&height="+height+"&weight="+weight;
    xmlHttp.open("get","bmiAjax?"+param,true);
    //发送 ajax 异步请求 
    xmlHttp.send();
 }
</script>

4.4 根据省份 id 查询省份名称

需求:用户在文本框架输入省份的编号 id,在其他文本框显示省份名称
项目环境准备:
1)数据库:springdb
2)数据表:

省份信息表:

SET FOREIGN_KEY_CHECKS=0 ;
DROP TABLE IF EXISTS `pro`;
CREATE TABLE `pro`(
  `id`int(11) NOT NULL AUTO_INCREMENT ,
  `name`varchar(255) DEFAULT NULL COMMENT '省份名称',
  `jiancheng`varchar(255) DEFAULT NULL COMMENT '简称',
  `shenghui` varchar(255) DEFAULT NULL,
PRIMARY KEY(`id`)
)ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 ;


INSERT INTO `pro` VALUES ('1','河北','冀','石家庄');
INSERT INTO `pro` VALUES ('2','山西','晋','太原市');
INSERT INTO `pro` VALUES ('3','内蒙古','蒙','呼和浩特市');
INSERT INTO `pro` VALUES ('4','辽宁','辽','沈阳');
INSERT INTO `pro` VALUES ('5','江苏','苏','南京');
INSERT INTO `pro` VALUES ('6','浙江','浙','杭州');
INSERT INTO `pro` VALUES ('7','安徽','皖','合肥');
INSERT INTO `pro` VALUES ('8','福建','闽','福州');
INSERT INTO `pro` VALUES ('9','江西','赣','南昌');

城市信息表:

SET FOREIGN_KEY_CHECKS=0 ;
DROP TABLE IF EXISTS `city`;
CREATE TABLE `city` (
`id` int (11) NOT NULL AUTO_INCREMENT ,
`name` varchar (255) DEFAULT NULL,
`provinceid` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT= 17 DEFAULT CHARSET=utf8 ;

INSERT INTO `city` VALUES ('1','石家庄','1') ;
INSERT INTO `city` VALUES ('2','秦皇岛','1') ;
INSERT INTO `city` VALUES ('3','保定市','1') ;
INSERT INTO `city` VALUES ('4','张家口','1') ;
INSERT INTO `city` VALUES ('5','南昌市','9') ;
INSERT INTO `city` VALUES ('6','九江市','9') ;
INSERT INTO `city` VALUES ('7','宜春市','9') ;
INSERT INTO `city` VALUES ('8','福州市','8') ;
INSERT INTO `city` VALUES ('9','厦门市','8') ;
INSERT INTO `city` VALUES ('10','泉州市','8') ;
INSERT INTO `city` VALUES ('11','龙岩市','8') ;
INSERT INTO `city` VALUES ('12','太原市','2') ;
INSERT INTO `city` VALUES ('13','大同','2') ;
INSERT INTO `city` VALUES ('14','呼和浩特','3') ;
INSERT INTO `city` VALUES ('15','包头','3') ;
INSERT INTO `city` VALUES ('16','呼伦贝尔','3') ;

项目结构:

img

项目是一个 web 应用, index.jsp 发送请求, SearchServlet 接收请求, 调用 ProvinceDao
从数据库获取指定 id 的省份名称。

实现步骤:

1. 在 idea 新建 web application

项目名称 ajaxweb

img

2. 配置 tomcat 服务器

img

3. 在 index.jsp 中创建 XMLHttpRequest 对象

定义表单:

 <body>
    <p>Ajax根据省份id获取名称</p>
    <table>
      <tr>
        <td>省份编号:</td>
        <td>
          <input type="text" id="proid">
          <input type="button" value="搜索" onclick="search()">
        </td>
      </tr>
      <tr>
        <td>省份名称:</td>
        <td><input type="text" id="proname"></td>
      </tr>
    </table>
  </body>

4. 创建 XMLHttpRequest 对象

<script type="text/javascript">
      function search(){
        // 发起Ajax请求,传递参数给服务器,服务器返回数据
        // 1.创建异步对象
        var xmlHttp = new XMLHttpRequest();
        // 2.绑定事件
        xmlHttp.onreadystatechange = function(){
          if( xmlHttp.readyState == 4 && xmlHttp.status == 200 ){
            var data = xmlHttp.responseText;
            // 更新dom对象,更新页面数据
            document.getElementById("proname").value = xmlHttp.responseText;
          }
        }
        // 3.初始异步对象
        // 获取proid文本框的值
        var proid = document.getElementById("proid").value;
        xmlHttp.open("get","queryInfoServlet?proid=" + proid,true);
        // 4.发送请求
        xmlHttp.send();
      }
</script>

5. 创建ProvinceDao 访问数据库

import java.sql.*;
// 使用jdbc访问数据库
public class ProvinceDao {

    // 根据id获取名称
    public String queryProvinceNameById(Integer provinceId){
        Connection conn = null;
        PreparedStatement pst = null;
        ResultSet rs = null;
        String sql = "";

        String url = "jdbc:mysql://localhost:3306/springdb?serverTimezone=UTC";
        String username = "root";
        String password = "123456";
        String name = "";

        // 加载驱动
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(url,username,password);
            // 创建prepareStatement
            sql = "select name from pro where id=?";
            pst = conn.prepareStatement(sql);
            // 设置参数值
            pst.setInt(1,provinceId);
            // 执行sql
            rs = pst.executeQuery();
            // 遍历rs
//            while(rs.next()){ // 当你的rs中有多于一条记录时
//                name = rs.getString("name");
//            }
            if(rs.next()){ // 因为记录集就一行
                name = rs.getString("name");
            }
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        } finally {
            try{
                if(rs != null){
                    rs.close();
                }
                if(pst != null){
                    pst.close();
                }
                if(conn != null){
                    conn.close();
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        return name;
    }
}

6. 创建 Servlet 处理 Ajax 请求

@WebServlet(name = "QueryInfoServlet", value = "/queryInfoServlet")
public class QueryInfoServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 处理get请求
        System.out.println("响应了Ajax请求");
        String strProid = request.getParameter("proid");
        System.out.println("strProid");

        String name = "默认是无数据";
        // 访问dao,查询数据库
        if(strProid != null){
            // 创建dao对象,调用它的方法
            ProvinceDao dao = new ProvinceDao();
            name = dao.queryProvinceNameById(Integer.valueOf(strProid));
        }

        // 使用HttpServletResponse输出数据
        response.setContentType("text/html;charset=utf-8");
        PrintWriter pw = response.getWriter();
        // pw.println("中国");
        pw.println(name);
        pw.flush();
        pw.close();
    }
}

7. web.xml 文件,注册 servlet

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>QueryInfoServlet</servlet-name>
        <servlet-class>com.ding.controller.QueryInfoServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>QueryInfoServlet</servlet-name>
        <url-pattern>/queryInfoServlet</url-pattern>
    </servlet-mapping>
</web-app>

4.5 使用 json 作为数据交换格式

需求:根据省份编号 id,查询省份的全部数据,数据格式 json
项目结构:

img

实现步骤:

1. 添加处理 json 的工具库

jackson:是非常有名的处理 json 的工具库。使用 jackson 可以实现 java 对象到 json 格式字符串的转换,也可以实现 json 字符串转为 json 对象。
把下面三个 jar 文件复制到/WEB-INF/lib 目录中。

img

其他步骤同 添加 mysql 驱动

2. 创建实体类 Province

public class Province {

    private Integer id;
    private String name;
    private String jiancheng;
    private String shenghui;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getJiancheng() {
        return jiancheng;
    }

    public void setJiancheng(String jiancheng) {
        this.jiancheng = jiancheng;
    }

    public String getShenghui() {
        return shenghui;
    }

    public void setShenghui(String shenghui) {
        this.shenghui = shenghui;
    }

}

3. 在 ProvinceDao 中增加方法,返回对象

方法定义:

import java.sql.*;

// 使用jdbc访问数据库
public class ProvinceDao {

    // 根据id获取名称
    public String queryProvinceNameById(Integer provinceId){
        Connection conn = null;
        PreparedStatement pst = null;
        ResultSet rs = null;
        String sql = "";

        String url = "jdbc:mysql://localhost:3306/springdb?serverTimezone=UTC";
        String username = "root";
        String password = "123456";
        String name = "";

        // 加载驱动
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(url,username,password);
            // 创建prepareStatement
            sql = "select name from pro where id=?";
            pst = conn.prepareStatement(sql);
            // 设置参数值
            pst.setInt(1,provinceId);
            // 执行sql
            rs = pst.executeQuery();
            // 遍历rs
//            while(rs.next()){ // 当你的rs中有多于一条记录时
//                name = rs.getString("name");
//            }
            if(rs.next()){ // 因为记录集就一行
                name = rs.getString("name");
            }
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        } finally {
            try{
                if(rs != null){
                    rs.close();
                }
                if(pst != null){
                    pst.close();
                }
                if(conn != null){
                    conn.close();
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        return name;
    }

    // 根据id获取一个完整的Province对象
    public Province queryProvinceById(Integer provinceId){
        Connection conn = null;
        PreparedStatement pst = null;
        ResultSet rs = null;
        String sql = "";

        String url = "jdbc:mysql://localhost:3306/springdb?serverTimezone=UTC";
        String username = "root";
        String password = "123456";
        Province province = null;

        // 加载驱动
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(url,username,password);
            // 创建prepareStatement
            sql = "select id,name,jiancheng,shenghui from pro where id=?";
            pst = conn.prepareStatement(sql);
            // 设置参数值
            pst.setInt(1,provinceId);
            // 执行sql
            rs = pst.executeQuery();
            // 遍历rs
//            while(rs.next()){ // 当你的rs中有多于一条记录时
//                name = rs.getString("name");
//            }
            if(rs.next()){
                province = new Province();
                province.setId( rs.getInt("id") );
                province.setName( rs.getString("name") );
                province.setJiancheng( rs.getString("jiancheng") );
                province.setShenghui( rs.getString("shenghui") );
            }
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        } finally {
            try{
                if(rs != null){
                    rs.close();
                }
                if(pst != null){
                    pst.close();
                }
                if(conn != null){
                    conn.close();
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        return province;
    }
}

4. 创建新的 Servlet 对象

img

5. 创建 searchJson.jsp,获取 json 数据

页面定义:

<body>
    <p>Ajax请求使用json格式的数据</p>
    <table>
        <tr>
            <td>省份编号:</td>
            </td>
                <input type="text" id="proid" >
                <input type="button" value="搜索" onclick="doSearch()">
            </td>
        </tr>
        <tr>
            <td>省份名称:</td>
            </td>
                <input type="text" id="proname" >
            </td>
        </tr>
        <tr>
            <td>省份简称:</td>
            </td>
            <input type="text" id="projiancheng" >
            </td>
        </tr>
        <tr>
            <td>省会:</td>
            </td>
            <input type="text" id="proshenghui" >
            </td>
        </tr>
    </table>
</body>

AJAX 请求处理:

<script type="text/javascript">
    function doSearch(){
      // 1.创建异步对象
      var xmlHttp = new XMLHttpRequest();

      // 2.绑定事件
      xmlHttp.onreadystatechange = function (){
        if( xmlHttp.readyState == 4 && xmlHttp.status == 200 ){
          var data = xmlHttp.responseText;
          var jsonobj = eval("(" + data + ")");
                        // eval是执行括号中的代码,把json字符串转为json对象
          // 更新dom对象
          document.getElementById("proname").value = jsonobj.name;
          document.getElementById("projiancheng").value = jsonobj.jiancheng;
          document.getElementById("proshenghui").value = jsonobj.shenghui;
        }
      }
      // 3. 初始异步对象的数据
      var proid = document.getElementById("proid").value;
      xmlHttp.open("get","queryInfoServlet?proid=" + proid,true);

      // 4.发起请求
      xmlHttp.send();
    }
  </script>

6. 部署应用,浏览器访问

img

4.6 异步请求

XMLHttpRequest 对象 open( method , url, true ) 第三个参数 true 表示异步请求

异步请求特点:

  1. 某一个时刻,浏览器可以委托多个异步请求对象发送请求,无需等待请求处理完成。
  2. 浏览器委托异步请求对象工作期间,浏览器处于活跃状态。可以继续向下执行其他命令。
  3. 当响应就绪后再对响应结果进行处理

实现步骤:

1. 设置异步对象 open 方法第三个参数为 true

//初始请求参数
xmlHttp.open("get","searchProvinceJson?proid="+proid,true);

2. send()后面,增加 alert()

//发送请求
xmlHttp.send();
alert("我是在异步请求之后的执行代码") 

3. SearchServletJson 类的 doGet 方法第一个加入断点

img

4. 部署应用,在浏览器访问应用

点击“搜索”按钮,请求发送到 Servlet,程序暂停执行, js 中 alert 执行继续执行,没有等待请求处理完成,浏览器窗口弹窗“我是在异步请求之后的执行代码”字符串。

1.4.7 同步请求

XMLHttpRequest 对象 open( method , url, false ) 第三个参数 false 表示同步请求同步请求特点:

  1. 某一个时刻,浏览器只能委托一个异步请求对象发送请求,必须等待请求处理完成。
  2. 浏览器委托异步请求对象工作期间,浏览器处于等待状态。不能执行其他命令。
  3. 不推荐使用。

实现步骤:同 4.3 步骤,需要 open(method,url,false)第三个参数设为 false

posted @ 2021-07-31 18:14  王陸  阅读(129)  评论(0编辑  收藏  举报