Ajax学习笔记
已完结,请放心食用~
全局刷新和局部刷新
01 全局刷新
整个浏览器被新的数据覆盖,在网络中传输大量的数据,浏览器需要加载,渲染页面
02 局部刷新
在浏览器的内部,发起请求,获取数据,改变页面中的部分内容
局部刷新的速度更快,可以按需获取数据
ajax是用来做局部刷新的,局部刷新使用的核心对象是 异步对象(XMLHttpRequest)
这个异步对象是存在浏览器内存中的,使用javascript语法创建和使用 XMLHttpRequest 对象
Ajax概念
-
Asynchronous Javascript and XML(异步的 Javascript 和 XML)
- Asynchronous:异步
- 同步只能处理一个请求
- 异步可以分开处理多个请求
- Javascript:Javascript脚本,在浏览器中执行
- and:和
- xml:是一种数据格式
- Asynchronous:异步
-
Ajax是一种做局部刷新的新方法(2003年左右),不是一种语言。
-
Ajax包含的技术主要有JavaScript,dom,css,xml等等,核心是JavaScript和xml。
-
JavaScript负责创建异步对象,发送请求,更新页面的dom对象。
-
Ajax请求需要服务器端的数据。
-
xml:可扩展标记语言
-
网络中的传输的数据格式
-
目前使用 json 替换了 xml
-
<datas> <data1> Car_01 </data1> <data2> Car_02 </data2> <data3> Car_03 </data3> <data4> Car_04 </data4> </datas>
-
-
Ajax异步实现步骤
ajax中使用XMLHttpRequest对象
step 01 创建异步对象
var xmlHttp = new XMLHttpRequest();
step 02 给异步对象绑定事件
-
给异步对象绑定onreadstatechange事件,获知请求的状态的变化
-
onreadystatechange事件
- 当请求被发送到服务器时,我们需要执行一些基于响应的任务
- 当异步对象发起请求,获取了数据,都会触发这个事件
- 每当 readyState 改变时,就会触发 onreadystateChange 事件
-
这个事件需要指定一个函数,在函数中处理状态的变化
- 此事件可以指定一个处理函数function
-
bth.onclick = fun1(); // 点击这个按钮会触发fun1函数 function fun1(){ alert("按钮单击"); } // For example, xmlHttp.onreadystatechange = function(){ // 用匿名函数直接指定 // 处理请求的状态变化 if( xmlHttp.readyState == 4 && xmlHttp.status == 200 ){ // 数据已经返回来准备好了 && 网络请求是成功的 // 可以处理服务器端的数据,更新当前页面 var data = xmlHttp.responseText; // 获取服务器返回的数据,使用异步对象的属性 responseText document.getElementById("name").value = data; } }
-
XMLHttpRequest对象的三个重要的属性
-
onreadystatechange 属性
- 一个js函数名 或 直接定义函数,每当readyState属性改变时,就会调用该函数
-
readyState 属性:存有 XMLHttprequest 的状态,表示异步对象请求从0到4的状态变化
-
readyState == 0:请求未初始化,创建异步请求对象,var xmlHttp = new XMLHttpReaquest()
-
readyState == 1:初始化异步请求对象,xmlHttp.open( 请求方式,请求地址,true ) 。
-
readyState == 2:异步对象发送请求,xmlHttp.send() 。
-
readyState == 3:异步对象接收应答数据,从服务端返回数据,XMLHttpRequest 内部处理。
- 从服务器端获取了原始数据
- 此时3是异步对象内部使用,开发人员一般不用。
-
readyState == 4:异步请求对象已经将数据解析完毕,此时才可以读取数据。
- 异步对象把接受的数据处理完成(数据是已经处理好的)。
- 此时开发人员在4的时候处理数据。
- 在 4 的时候,开发人员做什么?——> 更新当前页面。
-
-
state 属性:表示网络请求的状况
- 当 status == 200 时,表示网络请求是成功的
- 当 status == 404 时
- 当 status == 500 时
-
step 03 初始异步请求对象
-
异步的方法 open()
-
xmlHttp.open(请求方式get|post,"服务端的访问地址",同步|异步请求)
-
同步|异步请求:默认为true,表示异步请求
-
xmlHttp.open("get","loginServlet?name=zhangsan&pwd=123",true);
-
step 04 使用异步对象发送请求
- xmlHttp.send()
step 补充说明
-
获取服务器返回的数据,使用异步对象的属性 responseText
- 使用例子:xmlHttp.reponseText
-
使用需要配合服务器端,因为需要到服务端拿数据,单独使用没有意义
-
回调:当请求的状态变化时,异步对象会自动调用 onreadystatechange事件 对应的函数
- 完成整个流程,异步对象内部会多次调用这个函数
Ajax举例:计算BMI
BMI简介
- 需求
- 计算某个用户的BMI,用户在jsp输入自己的身高,体重
- servlet中计算BMI,并显示BMI的计算结果和建议
- BMI指数
- 身体质量指数(BodyMassindex)
- 体重公斤数除以身高米数平方得出的数字
- 目前国际上常用的衡量人体胖瘦程度以及是否健康的一个标准
- 成人的 BMI 数值
- 过轻:低于18.5
- 正常:18.5 ~ 23.9
- 过重:24 ~ 27
- 肥胖:28 ~32
- 非常肥胖:高于32
全局刷新方式
step 01 创建新项目
- idea创建新项目
- 创建空白项目,name自定义
- 右键项目文件夹,Add Framework Support...
- 选择 Java EE \ Web Application(默认version 4.0,勾选Create web.xml)
step 02 查看目录结构
- src
- web
- WEB-INF \ web.xml
- index.jsp
- project_name.imi
step 03 编写服务器页面
-
第一步:打开 index.jsp 页面
- 打开 web \ index.jsp 文件,设计页面布局
- 标题 title 标签自定义
- 提示文字 p 标签自定义
- form表单用来提交数据
- 需要的参数:姓名、体重、身高
-
第二步:准备服务器端
- (1)创建 Servlet
- Package:com.XXX.controller
- 不勾选其他项
- (2)设置 tomcat
-
-
-
-
- 最后打开 tomcat \ bin \ tomcat.exe 启动服务
- 不然会出大问题!(tomcat服务更新异常,无法更新或更新不完全)
-
- (3)创建 jsp 结果页面
- web 目录下创建 jsp 页面,以便实现 index.jsp(首页)到 result.jsp 的跳转
- (1)创建 Servlet
-
第三步:编写服务器端
-
(1)编写 web.xml
-
标签对 -
xml文件中给出了 servlet 标签对 的内容
-
<servlet> <servlet-name>Servlet模块名</servlet-name> <servlet-class>com.XXX.controller(包名).Servlet模块名</servlet-class> </servlet>
-
-
标签对 -
编写 servlet-mapping 标签对 的内容
-
<servlet-mapping> <servlet-name>Servlet模块名</servlet-name> <url-pattern>/路径访问地址</url-pattern> </servlet-mapping>
-
注意,若url路径落下 ” / “ ,启动 tomcat 会出现下图描述的报错
-
-
-
-
(2)编写 myServlet.java 类
-
src \ com.XXX.controller \ myServlet.java
-
在doGet()方法中编写程序
-
// 接收参数 String strname = request.getParameter("name"); String height = request.getParameter("height"); String weight = request.getParameter("weight");
-
// 计算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 = "您的身材是正常的"; }else if ( bmi > 24 && bmi <27){ msg = "您的身材较胖"; }else { msg = "您的身材过胖"; } System.out.println("msg="+msg); msg = "您好," + strName + "先生/女士,您的BMI指数为:" + bmi + "," + msg;
-
// 把数据存入到request request.setAttribute("msg",msg);
-
// 转发到新的页面 request.getRequestDispatcher("/result.jsp").forward(request,response);
-
-
(3)编写 result.jsp 页面
-
web \ result.jsp
-
<title>结果页面</title> <p>显示BMI计算结果</p> <h3>${msg}</h3>
-
-
-
第四步:运行tomcat,访问8080端口
step 补充说明
-
改写 myServlet.java 类
-
更改其中数据输出方式(使用应答对象输出数据)
-
/* // 把数据存入到request request.setAttribute("msg",msg); // 转发到新的页面 request.getRequestDispatcher("/result.jsp").forward(request,response); */
-
// 使用HttpServletResponse输出数据 response.setContentType("text/html;charset=utf-8"); // 获取PrintWriter PrintWriter pw = response.getWriter(); // 输出数据 pw.println(msg); // 清空缓存 pw.flush(); // 关闭close pw.close();
-
成功运行!
-
局部刷新方式
概述
使用ajax的局部刷新
1.新建jsp,使用XMLHttpRequest异步对象。
使用异步对象有四个步骤:
1.创建
2.绑定事件
3.初始请求
4.发送请求
2.创建服务器的servlet,接收并处理数据,把数据输出给异步对象。
step 01 创建新项目 / 新模块
- 创建新项目同全局刷新方式
- 创建新模块,注意为了方便区分可以把根目录设为和原模块(项目)同级
step 02 查看目录结构
- 查看目录结构同全局刷新方式
step 03 编写服务器页面
-
第一步:打开 index.jsp 页面
-
打开 web \ index.jsp 文件,设计页面布局
-
标题 title 标签自定义
-
提示文字 p 标签自定义
-
div 标签圈定范围
-
input 标签设置id,以便后续...
-
input 标签设置 onclick 触发 doAjax() 函数
-
注意,Ajax的数据传输不是通过form表单提交的
-
<!-- 写在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>
-
-
第二步:准备服务器端
- (1)创建 Servlet
- (2)设置 tomcat
- 补充:如果是子模块使用同项目配置好的tomcat,只需要设置:
-
-
第三步:编写服务器端
-
(1)编写 web.xml
-
<servlet> <servlet-name>MyBmiAjaxServlet</servlet-name> <servlet-class>com.ding.controller.MyBmiAjaxServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>MyBmiAjaxServlet</servlet-name> <url-pattern>/myBmiAjaxServlet</url-pattern> </servlet-mapping>
-
-
(2)编写 myServlet.java 类
-
@WebServlet(name = "MyBmiAjaxServlet", value = "/MyBmiAjaxServlet") public class MyBmiAjaxServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("接受了Ajax的请求"); // 接收参数 String strName = request.getParameter("name"); String weight = request.getParameter("weight"); String height = request.getParameter("height"); // 计算BMI float h = Float.valueOf(height); float w = Float.valueOf(weight); float bmi = w / ( h * h ); String msg; // 判断bmi的范围 if ( bmi < 18.5 ){ msg = "您的身材较瘦"; }else if ( bmi >= 18.5 && bmi <= 23.9 ){ msg = "您的身材是正常的"; }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(); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
-
-
编写 index.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>
-
-
局部刷新方式原理初探
从全局刷新到局部刷新
step 01 创建新项目 / 新模块
step 02 查看目录结构
step 03 编写服务器页面
-
第一步:打开 index.jsp 页面
-
第二步:准备服务器端
-
【上述三大步二小步同局部刷新方式步骤内容】
-
第三步:编写服务器端
-
重写服务器端 Version 1.0
-
目的:验证异步对象是否可以发起请求
-
更改对象:myServlet.java
-
// 以下内容均写在doGet()方法中 System.out.println("接受了Ajax的请求");
-
如果这句话可以输出(控制台可以显示),说明请求发起成功
-
web.xml设置路径
-
启动 tomcat,服务成功发布
-
证明异步对象确实可以发起请求啦
-
// 异步对象在发起请求的过程中是有状态变化的(5种状态)
-
-
重写服务器端 Version 2.0
-
目的:观察异步对象发起请求过程中的状态变化
-
更改对象:index.jsp
-
<!-- 写在head中 --> <script type="text/javascript"> // 使用内存中的异步对象,代替浏览器发起请求。异步对象是使用js创建和管理的。 function doAjax(){ // 1.创建异步对象 var xmlHttp = new XMLHttpRequest(); // 2.绑定事件 xmlHttp.onreadystatechange = function (){ // 处理服务器端返回的数据,更新当前页面 alert("readyState属 性值====" + xmlHttp.readyState); } // 3.初始请求数据 xmlHttp.open("get","bmiAjax",true); // 4.发起请求 xmlHttp.send(); } </script>
-
-
-
-
-
服务器端是空数据,但整个流程步骤完成执行,所以状态码变化为 0 => 1 => 2 => 4(0看不到)
-
-
重写服务器端 Version 3.0
-
在 index.jsp 加上状态码,观察其变化
-
// 2.绑定事件 xmlHttp.onreadystatechange = function (){ // 处理服务器端返回的数据,更新当前页面 alert("readyState属性值====" + xmlHttp.readyState + " | status:" + xmlHttp.status); }
-
-
-
-
-
-
重写服务器端 Version 4.0
-
目的:观察异步对象发起请求过程中完整的状态变化
-
更改对象:myServlet.java
-
// 写在doGet()方法中 System.out.println("接受了Ajax的请求"); PrintWriter pw = response.getWriter(); pw.println("Hello,Ajax!"); pw.flush(); pw.close();
-
-
-
-
-
-
重写服务器端 Version 5.0
-
目的:观察异步对象发起请求过程中完整的状态变化
-
更改对象:index.jsp
-
// 2.绑定事件 xmlHttp.onreadystatechange = function (){ // 处理服务器端返回的数据,更新当前页面 if( xmlHttp.readyState == 4 && xmlHttp.status == 200 ){ alert(xmlHttp.responseText); } }
-
-
点击按钮弹窗后,数据并未发生变化
-
- 按钮中有一个异步对象xmlHttp,该异步对象发起请求
- 把数据给Servlet,Servlet又把数据给了异步对象xmlHttp
-
-
-
重写服务器端 Version 5.0
-
传参
-
怎么获取身高、体重、姓名的数据呢? ==> dom对象的值
-
更改对象:index.jsp
-
访问地址:使用get方式传递参数
http://localhost:8080/Ajax_Dongli_war_exploded/bmiPrintServlet?name=张三&weight=100&height=1.85 -
// 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; alert("param=" + param); xmlHttp.open("get","bmiAjax?" + param,true);
-
-
-
重写服务器端 Version 5.1
-
收参
-
更改对象:myServlet.java
-
// 写在doGet()方法中 System.out.println("接受了Ajax的请求"); // 接收参数 String strName = request.getParameter("name"); String weight = request.getParameter("weight"); String height = request.getParameter("height"); // 计算BMI float h = Float.valueOf(height); float w = Float.valueOf(weight); float bmi = w / ( h * h ); String msg; // 判断bmi的范围 if ( bmi < 18.5 ){ msg = "您的身材较瘦"; }else if ( bmi >= 18.5 && bmi <= 23.9 ){ msg = "您的身材是正常的"; }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();
-
-
-
重写服务器端 Version 5.2
-
拿到数据之后如何更新页面?
-
更改页面:index.jsp
-
<!-- 在jsp页面body标签的div标签内添加如下代码 --> <br/> <br/> <div id = "mydata">等待加载数据......</div>
-
// 在jsp页面head标签的script标签内修改如下代码 // 2.绑定事件 xmlHttp.onreadystatechange = function (){ // 处理服务器端返回的数据,更新当前页面 if( xmlHttp.readyState == 4 && xmlHttp.status == 200 ){ // alert(xmlHttp.responseText); var data = xmlHttp.responseText; // 更新dom对象,更新页面数据 document.getElementById("mydata").innerText = data; } }
-
将关于弹窗提示的测试代码注释掉
-
-
Ajax举例:根据省份id查询省份名称
查询概述
-
需求:用户在文本框架输入省份的编号id,在其他文本框显示省份名称
-
项目环境准备
-
数据库:springdb
-
数据表
-
省份信息表
-
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') ;
-
-
-
局部刷新方式
step 01 创建新项目
- 创建空白项目
- 右键点击添加框架支持(Add Framework Support...)
- 选择 Java EE \ Web Application
- 在 web \ WEB-INF 下新建 classes 和 libs 文件夹
- 在项目结构(Project structs)下设置自定义编译输出路径为新建的classes文件夹
- 在项目结构(Project structs)下设置 tomcat 依赖和检查 factes 的 sources root 是否勾选
- src 右键创建新的Servlet模块
step 02 准备连接数据库
- jar包准备
- 将项目所需要的jar包cv到 web \ WEB-INF 下新建的 libs 文件夹中
- 前缀 jackson 的 jar包是做 json 用到的,mysql...是mysql连接数据库的驱动
- 将 jar 包加入到项目中,让项目可以识别 jar 包
- Project Structs ——> 选中项目 ——> modules ——> depenencies ——> 添加四个 jar 包
- Project Structs ——> Problems ——> 每个问题右键点击添加 jar 包
step 03 搭建页面结构
-
编写 web.xml
-
<?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>
-
-
编写 index.jsp
-
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Ajax根据省份id获取名称</title> <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> </head> <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> </html>
-
-
编写 Dao层
-
package com.ding.dao; 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; } }
-
-
编写 myServlet.java 类
-
package com.ding.controller; import com.ding.dao.ProvinceDao; import jakarta.servlet.*; import jakarta.servlet.http.*; import jakarta.servlet.annotation.*; import java.io.IOException; import java.io.PrintWriter; @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(); } }
-
JSON
什么是 Json
如果我们从服务器端返回的数据不是一个而是多个
比如从服务器端返回的数据包括省会的名称、简称等,此时返回文本框内的值就不方便了
所以这里使用json数据交换格式。
Ajax发起请求 ——> Servlet
Servlet返回的一个Json格式的字符串
( 字符串中有多个数据,包括名称、简称等 { name:"河北" , jiancheng:"冀","shenghui:"石家庄" } )
json分类
01 json对象
JSONObject,这种对象的格式是 名称:值 (所谓的“名称-值对”),也可以看作是 key : value 格式
{名称 : 值} 或者说 { key : value }
02 json数组
JSONArray,基本格式 [ { name:"河北" , jiancheng:"冀","shenghui:"石家庄" } , {name:"山西" , jiancheng:"晋","shenghui:"太原"} ]
[ { name:"河北" , jiancheng:"冀","shenghui:"石家庄" } , {name:"山西" , jiancheng:"晋","shenghui:"太原"} ]
Why Json?
01 json格式理解简单,含义清晰
02 json格式数据在多种语言中比较容易处理。使用java、js等读写json格式的数据比较容易
03 json格式数据占用的空间小,在网络中传输的速度快,用户的体验好
Jackson工具库
Java中处理json的工具库:gson,fastjson,jackson,json-lib
在程序中如何处理json?
使用jackson工具库,把一个java对象转为一个json格式的字符串
Aajx+JSON举例:根据省份id查询省份名称
// 那么需要有一个java对象
// 创建数据表对应的实体类
局部刷新方式
概述
使用ajax的局部刷新
1.新建jsp,使用XMLHttpRequest异步对象。
使用异步对象有四个步骤:
1.创建
2.绑定事件
3.初始请求
4.发送请求
2.创建服务器的servlet,接收并处理数据,把数据输出给异步对象。
step 01 创建新项目 / 新模块
- 创建新项目同全局刷新方式
- 创建新模块,注意为了方便区分可以把根目录设为和原模块(项目)同级
step 02 查看目录结构
- 查看目录结构同全局刷新方式
step 03 编写服务器页面
-
第一步:打开 index.jsp 页面
-
创建使用 json 的页面
-
打开 web \ index.jsp 文件,设计页面布局
-
标题 title 标签自定义
-
提示文字 p 标签自定义
-
div 标签圈定范围
-
input 标签设置id,以便后续...
-
input 标签设置 onclick 触发 doAjax() 函数
-
注意,Ajax的数据传输不是通过form表单提交的
-
输入一个省份的编号,有很多数据信息返回,更新dom页面
-
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>使用json格式的数据</title> </head> <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> </html>
-
-
第二步:准备服务器端
- (1)创建 Servlet
- (2)设置 tomcat
- 补充:如果是子模块使用同项目配置好的tomcat,只需要设置:
-
-
第三步:编写服务器端
-
搭建服务器端的基本结构
- com \ ding \ controller \ QueryInfoServlet.java
- com \ ding \ dao\ ProvinceDao.java
- com \ ding \ entity \ Province.java
-
(1)编写 web.xml
-
<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>
-
-
(2)编写entity层 Province.java
-
package com.ding.entity; 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)编写 dao层 ProvinceDao.java
-
dao层返回一个province对象
-
package com.ding.dao; import com.ding.entity.Province; 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)编写 myServlet.java 类
-
package com.ding.dao; import com.ding.entity.Province; 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; } }
-
写完servlet,还没写ajax的请求呢,先测试一下servlet能不能用(可不可以正常返回数据)
-
serlvet写完之后测一下
-
-
-
编写 index.jsp 页面
-
在js中,可以将json格式的字符串,转为json对象,json中的key,就是json对象的属性名
-
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>使用json格式的数据</title> <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> </head> <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> </html>
-
-
同步和异步
open函数第三个参数的作用(true)
同步还是异步?——> 真表示异步,假表示同步;
true:异步处理请求,使用异步对象发起请求后,不用等待数据处理完毕就可以执行其他的操作
按理说,发送到servlet的数据,返回后才可以继续使用,但异步可以同时处理多个请求
不会妨碍其他代码的执行
同步的方式,在任意时刻只能执行一个请求