Ajax
1 - ajax技术
1.全局刷新和局部刷新
全局刷新:整个浏览器被新的数据覆盖,在网络中传输大量的数据,浏览器需要加载,渲染页面
局部刷新:在浏览器的内部,发起请求,获取数据,改变页面中的部分内容,其余的页面无需加载和渲染,网络中数据传输量少,给用户的感受号。
ajax是用来做局部刷新的。局部刷新使用的核心对象是 异步对象 (XMLHttpRequest),这个异步对象是存在浏览器内存中,使用JavaScript语法创建和使用XMLHttpRequest对象
2.ajax:Asynchronous JavaScript and XML (异步的 JavaScript 和 XML)
ajax:是一种局部刷新的新方法,不是一种语言。ajax包含的技术主要有JavaScript,dom,css,xml等
JavaScript:负责创建异步对象,发送请求,更新页面的dom对象。ajax请求需要服务端的数据
xml:网络中传输的数据格式(但是现在都是使用json)
<数据><data>宝马1</data></数据>
2 - ajax异步实现步骤或开发步骤
1.新建jsp,使用XMLHttpRequest异步对象
使用异步对象有四个步骤:
1.创建
2.绑定事件
3.初始化请求
4.发送请求
2.创建服务器的servlet,接收并处理数据,把数据传输个异步对象
使用XMLHttpRequest 对象介绍
①创建异步对象 var xmlHttp = new XMLHttpRequest();
②给异步对象绑定事件。
btn.onclic = func1()
function fun1() {
alert("按钮单机");
}
onreadystatechange事件:当异步对象发起请求,我们需要执行一些基于响应的任务,每当readyState改变时,就会触发 onreadystatechange事件。此事件可以指定一个处理函数 function,在函数中处理状态的改变
例如:
xmlHttp.onreadystatechange = function(){
处理请求的状态变化
if(xmlHttp.readyState == 4 && xmlHttp.status == 200){
// 可以处理服务端的数据,完成更新当前页面
var data = xmlHttp.responseText;
document.getElementById("name").value = data;
}
}
异步对象的属性(readyState):
readyState 表示异步对象请求的状态变化
0:创建异步对象,new XMLHttpRequest();
1:初始化异步请求对象,xmlHttp.open()
2:发送请求,xmlHttp.send()
3:从服务器端获取了数据,此时3,,注意是异步对象内部使用,获取了原始的数据
4:异步对象把接收的数据处理完成后。此时开发人员在4的时候处理数据。即更新当前页面
异步对象的status属性,表示网络请求的状况的,200,404,500等,需要是当status == 200时,表示网络请求时成功
③初始异步请求对象
调用异步对象的open()方法
xmlHttp.open(请求方式get/post,"服务器端的访问地址",同步/异步请求(默认是true,异步请求))
例如:
xmlHttp.open("get","loginServlet?username=alex&password=123",true)
④使用异步对象发送请求
xmlHttp.send()
获取服务端返回的数据,使用异步对象的属性 responseText
使用例子:xmlHttp.responseText
回调:当请求的状态变化时,异步对象会自动调用onreadystatechange事件对应的函数
开发代码示例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>ajax-局部刷新</title> <script type="text/javascript"> // 使用内存中的异步对象,代替浏览器发起请求,异步对象使用js创建和管理 function countBMI(){ // 1.创建异步对象 var xmlHttp = new XMLHttpRequest(); // 2.绑定事件 xmlHttp.onreadystatechange = function () { // 处理服务端返的数据,更新当前页面 // alert("status:" + xmlHttp.status + "readyState:" + xmlHttp.readyState); if(xmlHttp.readyState == 4 && xmlHttp.status == 200){ // alert(xmlHttp.responseText); var data = xmlHttp.responseText; // 更新dom对象,更新页面数据 document.getElementById("myData").innerText = data; } }; // 3.初始化请求数据 // 获取dom对象的value属性值 var name = document.getElementById("name").value; var height = document.getElementById("height").value; var weight = document.getElementById("weight").value; var url = "bmi?name=" + name + "&height=" + height + "&weight=" + weight; xmlHttp.open("get",url,true); // 4.发起请求 xmlHttp.send(); } </script> </head> <body> <p>ajax-局部刷新,计算bmi</p> <div> Name<input type="text" id="name"><br> Weight(例如:60kg)<input type="text" id="weight"><br> height(例如:1.7m)<input type="text" id="height"><br> <input type="button" value="计算BMI" onclick="countBMI()"> <input type="reset"><br> <div id="myData"> </div> </div> </body> </html>
package com.howie.controller; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; public class BmiServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1.调用请求参对象,读取请求头参数信息,获取用户姓名,身高,体重信息 String name = request.getParameter("name"); String weight = request.getParameter("weight"); String height = request.getParameter("height"); // 2.计算BMI(BMI=体重/升高的平方) double bmi = Double.valueOf(weight) / Math.pow(Double.valueOf(height),2); // 3.判断BMI String message = null; if(bmi <= 18.5){ message = "您!比较瘦,今晚可以撸串吃火锅"; } else if(bmi > 18.5 && bmi <= 23.9){ message = "您的BMI是正常的"; } else if(bmi > 24 && bmi <= 27 ){ message = "您的身体比较胖"; } else{ message = "您的身体比较肥胖"; } System.out.println("message:" + message); message = "您好!" + name + "您的BMI值=" + bmi +",判断结果为[" + message + "]"; // 使用request请求作用域对象把数据返回给浏览器 /* // 4.把数据存入request请求作用域对象里 request.setAttribute("info",message); // 5.通过请求转发,向Tomcat申请调用info.jsp文件,把结果写入到响应体 request.getRequestDispatcher("/info.jsp").forward(request,response); */ // 响应ajax需要的数据,使用HttpServletResponse输出数据 response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); // 1.获取PrintWriter对象 out.print(message); // 2.输出数据 out.flush(); // 3.清空缓存,目的立刻向浏览器输出数据 out.close(); // 关闭资源 // response.setContentType("text/html;charset=utf-8"); // System.out.println("以接收到请求"); // PrintWriter out = response.getWriter(); // out.print("hello ajax"); } }
图解
3 - 使用json数据格式响应浏览器
1.ajax发起请求 --> servlet(返回的一个json格式的字符串 {name:"河北",jiancheng:"翼",shenghui:"石家庄"})
2.json分类:
1)json对象(JSONObject)
基本格式:{key:"value"}
2)json数组(JSONArray)
基本格式:[{key1:"value1"},{key2:"value2"}]
3.为什么要使用json?
1)json格式易于阅读与理解
2)json格式数据支持多种语言,也比较容易处理,使用Java,JavaScript读写json格式的数据比较容易
3)json格式数据它占用的空间小,在网络中传输快
4.处理json的工具库:
①gson(谷歌开发) ②fastjson(阿里开发) ③jackson ④json-lib
5.json对象
在js中,可以把json格式的字符串,转为json对象,json中的key,就是json对象的属性名
6.代码示例
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1.调用请求对象,读取请求头参数信息,获取省份id String provinceId = request.getParameter("province_id"); Province province = null; String jsonProvince = "{}"; // 默认值,表示json格式的数据,当查询不到结果时,浏览器可以接收到一个json格式的字符串 // 2.调用ProvinceDao类的相关的方法,根据省份id推送SQL语句,获取一个省份实例对象 if(provinceId != null && !"".equals(provinceId.trim())){ ProvinceDao dao = new ProvinceDao(); province = dao.getAProvinceById(Integer.valueOf(provinceId)); // 3.使用Jackson,将province对象,转化为 json 格式的字符串 ObjectMapper om = new ObjectMapper(); jsonProvince = om.writeValueAsString(province); } // 4.把处理结果,以网络的形式传给ajax异步对象,响应结果数据 response.setContentType("application/json;charset=utf-8"); // 指明给浏览器返回json格式的数据 PrintWriter out = response.getWriter(); out.print(jsonProvince); // 此时数据会赋值给ajax异步对象的responseText属性 out.flush(); out.close(); }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>使用json格式的数据,完成ajax请求</title> <script type="text/javascript"> function searchById(){ // 1.创建异步对象 var xmlHttp = new XMLHttpRequest(); // 2.绑定事件 xmlHttp.onreadystatechange = function(){ if(xmlHttp.readyState == 4 && xmlHttp.status == 200){ var data = xmlHttp.responseText; // 处理数据完成更新页面(更新dom对象) var jsonObj = eval("(" + data + ")"); // eval() 把括号中的json字符串转为json对象 document.getElementById("name").value = jsonObj.name; document.getElementById("jiancheng").value = jsonObj.jiancheng; document.getElementById("shenghui").value = jsonObj.shenghui; } }; // 3.初始化异步对象 var provinceId = document.getElementById("province_id").value; var url = "queryJson?province_id=" + provinceId; xmlHttp.open("get",url,true); // 4.发送请求 xmlHttp.send(); }; </script> </head> <body> <table border="2px"> <tr> <td>省份的编号</td> <td> <input type="text" id="province_id"> <input type="button" value="搜索" onclick="searchById()"> </td> </tr> <tr> <td>省份名称</td> <td><input type="text" id="name"></td> </tr> <tr> <td>省份简称</td> <td><input type="text" id="jiancheng"></td> </tr> <tr> <td align="center">省会</td> <td><input type="text" id="shenghui"></td> </tr> </table> </body> </html>
4 - 异步处理请求与同步处理请求
function searchById(){
// 1.创建异步对象
var xmlHttp = new XMLHttpRequest();
// 2.绑定事件
xmlHttp.onreadystatechange = function(){
if(xmlHttp.readyState == 4 && xmlHttp.status == 200){
var data = xmlHttp.responseText;
// 处理数据完成更新页面(更新dom对象)
var jsonObj = eval("(" + data + ")"); // eval() 把括号中的json字符串转为json对象
document.getElementById("name").value = jsonObj.name;
document.getElementById("jiancheng").value = jsonObj.jiancheng;
document.getElementById("shenghui").value = jsonObj.shenghui;
}
};
// 3.初始化异步对象
var provinceId = document.getElementById("province_id").value;
var url = "queryJson?province_id=" + provinceId;
xmlHttp.open("get",url,true);
// true:异步处理请求。使用异步对象发起请求后,不用等待数据处理完毕,就可以执行其他的操作。此时也可以创建其他的 XMLHttpRequest,发送其他的请求处理。
// false:同步处理请求。异步对象必须处理完成请求,从服务端获取数据后,才能执行send之后的代码,任意时刻只能执行一个异步请求。
// 4.发送请求
xmlHttp.send();
};
5 - ajax思维导图
6 - 项目知识储备
1.get 请求和post请求的区别
get:取,拿,得到
在实际项目开发中,核心业务是以 查询为目的的,我们都是发出get请求
post:邮寄,邮递
1)在实际项目开发中,核心业务是以 添加,修改,删除 为目的,我们都是发出 post请求。
2)特殊情况,参数涉及到了安全性方面的问题,例如,登录,我们需要传递用户名,密码,需要使用post请求
2.关于同步和异步
设置 async:true 异步
通过观察得到结果,下面alert弹框没有等到上面的ajax执行完毕,就执行,全程两根线程(主线程执行普通代码,子线程执行ajax,且两根线程互相独立,互不影响)
设置 async:false 同步
通过观察得到结果,下面的alert弹框必须要等到上面的ajax执行完毕后,才能执行,全程一根线程,线程是按照代码从上向下的顺序依次执行
未来实际项目开发中,一般情况下,我们都是使用异步请求可以有效的提升用户体验,在特殊需求下,也会使用到同步
3.前后端传值方式
1)前端 -- > 后端
前端为后端传值,一般叫传参数(url?key=value,ajax data{})
以上都是前端为后端提供参数的方式,但是无论使用哪种形式为后端提供参数,后端一律使用 String value = request.getParameter(key)的形式来接收参数
例如:执行批量删除的操作
url/delete.do?id=1&id=2&id=3
String[] idList = request.getParameterValues("id");
2)后端 -- > 前端
json数据格式
4.Servlet模板模式的应用
1)在实际项目开发中,所谓的同时交流的设计模式,普遍指的是基于GoF的23种设计模式,这23种设计模式,所有面向对象语言通用(不仅仅针对Java语言)
2)模板模式是GoF23种设计模式的其中一种,它的功能是将程序执行的流程或者算法的骨架搭建出来,里面具体的实现方式交给方法去做
5.UUID的应用
主键:int/bigint
以前为什么使用整型?
因为整型能自动递增,开发时使用方便
例如:inert into tbl_student(name,age) values(?,?)
1)实际项目开发中,很少使用整型作为主键来使用,就是因为自动递增(添加是会先查找出最大的字段值,在最大的字段值基础上自增1),
2)实际项目开发中,使用字符串(UUID)当做主键字段型比较多。主键:非空+唯一。使用UUID会为我们生成一组由数字字母以及横杠所组成的随机串,这个随机串有36位,这个随机串一定是全世界唯一的。
1.为什么UUID是全世界唯一的
时间戳+随机数+硬件自身出厂机器编码
2.在数据库表当中,UUID生成的主键应该使用什么类型
varchar(32):变长
使用 char(32):定长。因为UUID转化出来的字符串的长度是固定的32个字符