1 AJAX
AJAX(Asynchronous JavaScript And XML) 异步的JavaScript(编程语言)和XML(文件格式)。
AJAX不是一门新的编程语言,是多门已有技术组合后创新产生的新技术。
核心点:
- 核心编程语言是JS
- 数据交换的工具是XML(现在已经被JSON替代)
- AJAX是一种异步请求方式(和同步请求对立)
2 同步请求和异步请求
2.1 同步请求
浏览器发起的传统请求(表单、超链接、地址栏、location.href),都是同步请求。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qTw1h6Ai-1681800041256)(AJAX day01.assets/同步请求流程.png)]
用户从发起请求开始,到服务端响应结果完毕,这段时间内不能在操作页面。如果服务端响应结果耗时很长,用户在这段时间一直等待,用户体验很差。
同步请求的特点:
- 一定刷新页面
- 地址栏一定改变
- 发起同步请求,会阻塞用户的其它操作
2.2 异步请求
AJAX是一种浏览器端的异步请求技术。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yu4NBtDw-1681800041257)(AJAX day01.assets/异步请求流程.png)]
AJAX请求,服务端响应回不是一个完整页面,而是字符串(页面局部),不会刷新页面。
用户在JS发起请求开始,到服务端响应结果完毕,不用等待。用户可以一直操作页面,用户体验好。
异步请求的特点:
- 不刷新页面
- 地址栏不改变
- 异步请求不会阻塞用户的其它操作
3 AJAX开发思路
AJAX技术核心对象是XMLHttpRequest对象,JS通过它和服务端建立连接,交换数据。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AosrAd2C-1681800041257)(AJAX day01.assets/ajax请求的大致思路.png)]
4 实战案例:校验用户名是否存在
在注册的时候我们要判断要注册的账号在数据库里面是否已经存在。如果存在就提示该账号不能注册,如果不存在就提示用户可以注册。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gJqHzQ2y-1681800041258)(AJAX day01.assets/1622528345676.png)]
4.1 前端代码:
用户名:<input type="text" name="username" οnblur="doAjax()"/><span id="msg"></span>
<script type="text/javascript">
function doAjax(){
// 1.创建xhr核心对象。
let xhr = new XMLHttpRequest();
// 2.指定发出请求的路径和请求方式。
let username=document.querySelector("input[name=username]").value;
xhr.open("get","${pageContext.request.contextPath}/user/checkUserName.do?name="+username);
// 3.设置回调函数。
//onreadystatechange是一个事件,等号后面是一个函数。状态改变事件。xhr有五个状态。
//0:表示刚创建出来。
//1:表示要发请求了。
//2:表示到达服务器
//3:表示服务器端开始响应数据
//4:表示浏览器接受到数据。
xhr.onreadystatechange=function(){
if(xhr.readyState==4) {//判断请求状态是否是4,我们才做处理
if(xhr.status==200) {//响应码,判断是否正常接受到响应。404,403,500
//从xhr中接受到响应信息。
let result=xhr.responseText;//服务端响应的结果
if(result==="true"){
//提示该 用户已经被注册
document.getElementById("msg").innerHTML="用户已经被注册";
}else{
//提示该用户可以被注册
document.getElementById("msg").innerHTML="可以注册该用户";
}
}
}
}
// 4.发出请求。
xhr.send();
}
</script>
4.2 服务端的代码:
<!--springmvc的包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!-- 跟响应数据的格式相关的一个依赖 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.0</version>
</dependency>
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("checkUserName")
@ResponseBody//告知springmvc我们响应信息不是一个jsp了,而是一个数据。
public Boolean checkUserName(String name){
return "zhangsan".equals(name);
}
}
5 JSON
AJAX是一种异步请求,在Client和Server端之间建立连接,交换数据。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5th5TO0J-1681800041258)(AJAX day01.assets/image-20200327101339340.png)]
异步请求下,Server端响应回Client不是一个完整的页面,而是字符串数据。当服务端响应的结果比较复杂时(对象、数组、集合),简单格式的字符串不能满足需求。在传递复杂的数据时,不能使用简单格式的字符串,而是使用JSON格式的字符串。
JSON(JavaScript Object Notation)JS对象字符串表示形式,定义了对象等复杂数据的特定字符串格式。独立于各个编程语言,是一种轻量级的数据交换格式。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yn5xmerY-1681800041258)(AJAX day01.assets/image-20200327102640172.png)]
6 JSON语法
6.1 普通对象和Map
json格式:
普通对象:{“属性名1”:属性值1,“属性名2”:属性值2,…}
Map集合:{“key1”:value1,“key2”:value2,…}
6.2 数组、List、Set
json格式:
[元素1,元素2,…]
7 Jackson的使用
在pom.xml引入依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.0</version>
</dependency>
7.1 普通对象和Map集合
@Test
public void testObject() throws JsonProcessingException {
Student s = new Student(1,"xiaohei",false,100.0,new Date());
//使用jackson转换普通对象
ObjectMapper mapper = new ObjectMapper();
String objectJson = mapper.writeValueAsString(s);
System.out.println("objectJson = " + objectJson);
}
//测试Map集合
@Test
public void testMap() throws JsonProcessingException {
Map<String, Object> map = new HashMap<>();
map.put("id",1);
map.put("name","xiaohei");
map.put("sex",false);
map.put("age",18);
map.put("score",100.0);
map.put("birthday",new Date());
//使用jackson转换map集合
ObjectMapper mapper = new ObjectMapper();
String mapJson = mapper.writeValueAsString(map);
System.out.println("mapJson = " + mapJson);
}
7.2 数组、List和Set
//测试数组
@Test
public void testArray() throws JsonProcessingException {
Object[] os = {1,"xiaohei",false,new Student(1,"xiaohei",false,100.0,new Date()),new Date()};
//使用jackson转换map
ObjectMapper mapper = new ObjectMapper();
String arrayJson = mapper.writeValueAsString(os);
System.out.println("arrayJson = " + arrayJson);
}
//测试List
@Test
public void testList() throws JsonProcessingException {
List<String> list = new ArrayList<>();
list.add("xiaohei");
list.add("xiaobai");
list.add("xiaohong");
list.add("xiaolv");
ObjectMapper mapper = new ObjectMapper();
String listJson = mapper.writeValueAsString(list);
System.out.println("listJson = " + listJson);
}
//测试Set
@Test
public void testSet() throws JsonProcessingException {
Set<String> set = new HashSet<>();
set.add("xiaohei");
set.add("xiaobai");
set.add("xiaohong");
set.add("xiaolv");
ObjectMapper mapper = new ObjectMapper();
String setJson = mapper.writeValueAsString(set);
System.out.println("setJson = " + setJson);
}
7.3 嵌套形式
@Test
public void testNest() throws JsonProcessingException {
Address address = new Address("郑州", "文化路硅谷广场");
List<String> favorites = new ArrayList<>();
favorites.add("吃");
favorites.add("喝");
favorites.add("睡");
Map<String, Double> scores = new HashMap<>();
scores.put("语文", 89.0);
scores.put("数学", 99.0);
scores.put("英语", 90.0);
User user = new User(1, "xiaohei", address, favorites, scores);
//使用jackson转换嵌套的对象
ObjectMapper mapper = new ObjectMapper();
String str = mapper.writeValueAsString(user);
System.out.println("str = " + str);
}
8 Jackson特殊情况的处理
8.1 null的处理
jackson默认会转换属性值为null的属性,可以在属性所在的类型上添加注解,不再转换null属性。
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Student implements Serializable {
private Integer studentId;
private String studentName;
private Boolean sex;
private Double score;
private Date birthday;
// get set 有参无参构造
...
}
8.2 对象的属性名和JSON字符串中属性名不一致
可以在属性上方添加JsonProperty注解,自定义转换后的属性名。
public class Student implements Serializable {
@JsonProperty("id")
private Integer studentId;
@JsonProperty("name")
private String studentName;
private Boolean sex;
private Double score;
private Date birthday;
// get set 有参无参构造
...
}
//转换结果示例:{"sex":false,"score":100.0,"id":1,"name":"xiaohei"}
8.3 日期格式
jackson默认将日期数据转换为ms(毫秒数),需要自定义转换格式,可以使用JsonFormat注解。
public class Student implements Serializable {
private Integer studentId;
private String studentName;
private Boolean sex;
private Double score;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date birthday;
...
}
9 springmvc和jackson集成处理ajax请求.
-
在方法上面添加@ResponseBody标签.
-
设置控制器的方法的返回值类型为对象,list集合,map集合,springmvc中会自动调用jackson的工具类将返回值转换为json对象.
@ResponseBody//该方法返回是一个具体值,不是一个jsp @RequestMapping("/check3") public User checkUserName3() throws JsonProcessingException { User user = new User(1,"zhangsan",20,new Address(1,"zhengzhou","文化路")); return user; }
10 Axios工具的使用
Axios 是一个基于 ES6 promise语法 的 HTTP 库,可以用在浏览器和 node.js 中。
10.1 核心方法
axios的核心方法:
- axios(config).then(回调函数);
axios({
method:"请求方式",//默认值get
url:"地址",//除了url是必选,其它参数都可省略
params:{//拼接在地址后的参数,与get请求配合使用。必须是对象
参数名1:参数值1,
参数名2:参数值2,
...
},
data:{//在请求体中发送的数据,与post请求配合使用。可以是对象也可以是字符串
属性名1:属性值1,
属性名2:属性值2,
...
}
}).then((resp)=>{//处理响应
resp.data;//响应的数据[重点]
resp.status;//状态码
resp.headers;//响应头
resp.config;//发送请求时的配置信息
}).catch((error)=>{//处理异常
console.log(error);
})
示例:
用户名:<input type="text" name="username" onblur="doAjax()"/><span id="msg"></span>
<script src="${pageContext.request.contextPath}/js/axios-0.21.0.js"></script>
<script type="text/javascript">
function doAjax(){
let username=document.querySelector("input[name=username]").value;
//发出ajax请求
axios({
method:"get",
url:"${pageContext.request.contextPath}/user/checkUserName.do",
params:{name:username}
}).then(function(resp){
let result=resp.data;//可以获取到服务器端的响应数据
if(result==="true"){
//提示该 用户已经被注册
document.getElementById("msg").innerHTML="用户已经被注册";
}else{
//提示该用户可以被注册
document.getElementById("msg").innerHTML="可以注册该用户";
}
})
}
</script>
10.2 在vue中使用axios函数
<div id="app">
用户名:<input type="text" name="username" @blur="doajax" v-model="user.name"/><span id="msg">{{msg}}</span>
</div>
<script src="${pageContext.request.contextPath}/js/vue-2.6.12.js"></script>
<script src="${pageContext.request.contextPath}/js/axios-0.21.0.js"></script>
<script type="text/javascript">
const vue=new Vue({
el:"#app",
data:{
user:{name:""},
msg:""
},
methods:{
doajax(){
//发ajax请求
axios({
method:"get",
url:"${pageContext.request.contextPath}/user/checkUserName.do",
params:this.user
}).then((resp)=>{
if(resp.data){
this.msg="该值已经被注册";
}else{
this.msg="改值可以被注册";
}
});
}
}
});
</script>
method:"get",
url:"${pageContext.request.contextPath}/user/checkUserName.do",
params:this.user
}).then((resp)=>{
if(resp.data){
this.msg="该值已经被注册";
}else{
this.msg="改值可以被注册";
}
});
}
}
});
```