第一节 Ajax概述
1、服务器端渲染
2、Ajax渲染(局部更新)
3、前后端分离
彻底舍弃服务器端渲染,数据全部通过Ajax方式以JSON格式来传递。
4、同步与异步
Ajax本身就是Asynchronous JavaScript And XML的缩写,直译为:异步的JavaScript和XML。在实际应用中Ajax指的是:不刷新浏览器窗口,不做页面跳转,局部更新页面内容
的技术。
『同步』
和『异步』
是一对相对的概念,那么什么是同步,什么是异步呢?
4.1、同步
多个操作按顺序执行
,前面的操作没有完成,后面的操作就必须等待
。所以同步操作通常是串行
的。
4.2、异步
多个操作相继开始并发执行
,即使开始的先后顺序不同,但是由于它们各自是在自己独立的进程或线程中
完成,所以互不干扰,谁也不用等谁
。
5、Axios简介
使用原生的JavaScript程序执行Ajax极其繁琐,所以一定要使用框架来完成。而Axios就是目前最流行的前端Ajax框架。
Axios官网:http://www.axios-js.com/
使用Axios和使用Vue一样,导入对应的*.js文件
即可。官方提供的script标签引入方式为:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
我们可以把这个axios.min.js文件下载下来保存到本地来使用。
第二节 Axios基本用法
1、在前端页面引入开发环境
<!--引入vue.js文件-->
<script language="JavaScript" src="script/vue.js"></script>
<!--引入axios.min.js文件-->
<script language="JavaScript" src="script/axios.min.js"></script>
2、发送普通请求参数
2.1、基本格式
客户端向服务器端异步发送普通参数值:使用params
表示
- 基本格式: axios().then().catch()
- 示例:
axios({
//括号里面是一个对象
method:"POST",
url:"....",
params:{
uname:"lina",
pwd:"ok"
}
})
//成功响应时执行的回调:then()
// value就是成功时服务器端返回的响应数据
// value.data可以获取到服务器响应体内容
.then(function(value){
})
//有异常时执行的回调catch():
// reason就是出错时服务器端返回的响应数据
// reason.response在服务器端处理请求失败后,获取axios封装的JSON格式的响应数据对象
// reason.response.data可以获取到响应的内容
// reason.response.status在服务器端处理请求失败后,获取响应状态码
// reason.response.statusText在服务器端处理请求失败后,获取响应状态说明文本
// reason.message / reason.stack 可以查看错误的信息
.catch(function(reason){
});
2.2、前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--引入vue.js文件-->
<script language="JavaScript" src="script/vue.js"></script>
<!--引入axios.min.js文件-->
<script language="JavaScript" src="script/axios.min.js"></script>
<script language="JavaScript">
window.onload=function(){
//文档就绪事件函数
var vue = new Vue({
el:"#div0",
data:{
uname:"lina",
pwd:"ok"
},
methods:{
axios01:function(){
axios({
method:"post",
url:"http://localhost:8080/Vue/axios01.do",
params:{
//注意:不能使用this.uname使能使用vue.uname,因为已经进入到axios中了,this代表的是axios
// 里面的属性,想要使用date中的属性只能通过vue来调用。
uname:vue.uname,
pwd:vue.pwd
}
})
.then(function (value) {
console.log(value);
})
.catch(function (reason) {
console.log(reason);
});
}
}
});
}
</script>
</head>
<body>
<div id="div0">
uname:<input type="text" v-model="uname"/><br/>
pwd:<input type="text" v-model="pwd"/><br/>
<input type="button" @click="axios01" value="发送一个带普通请求参数值的异步请求"/>
</div>
</body>
</html>
2.3、后端代码
package axios;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/axios01.do")//Servlet3.0使用注解代替原先的xml方式配置路径
public class Axios01Servlet extends HttpServlet {
private static final long serialVersionUID = -8499971529938553156L;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String uname = request.getParameter("uname");
String pwd = request.getParameter("pwd");
System.out.println("uname = " + uname);
System.out.println("pwd = " + pwd);
response.setCharacterEncoding("utf-8");
//设置返回的类型是普通文本
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.write(uname+"_"+pwd);
// throw new NullPointerException("这里故意抛出一个空指针异常....");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
P.S.:由于我们不需要Thymeleaf了,所以ModelBaseServlet可以跳过ViewBaseServlet直接继承HttpServlet。
2.4、运行测试
说明:启动Tomact,首先访问到demo10.html页面,在页面点击按钮执行点击事件,通过axios方式post请求。
可以看到在控制层方法中获取到了请求参数:
请求参数:所有请求参数都被放到URL地址后面了,哪怕我们现在用的是POST请求方式。
响应的内容:
2.5、DeBug查看成功响应的对象value结构
说明:使用js的DeBug调试,查看成功响应时执行的回调函数中的value参数值:
可以看到:data数据在value中
属性名 | 作用 |
---|---|
config | 调用axios(config对象)方法时传入的JSON对象 |
data | 服务器端返回的响应体数据 |
headers | 响应消息头 |
request | 原生JavaScript执行Ajax操作时使用的XMLHttpRequest |
status | 响应状态码 |
statusText | 响应状态码的说明文本 |
2.6、DeBug查看失败响应的对象reson结构
说明:使用js的DeBug调试,查看失败响应时执行的回调函数中的reson参数值:
可以看到:data数据在reson下面的response中。
可以看到:response对象的结构还是和then()函数传入的回调函数中的response是一样的:
回调函数:开发人员声明,但是调用时交给系统来调用。像单击响应函数、then()、catch()里面传入的都是回调函数。回调函数是相对于普通函数来说的,普通函数就是开发人员自己声明,自己调用:
普通函数:
function sum(a, b) {
return a+b;
}
var result = sum(3, 2);
console.log("result="+result);
3、发送请求体JSON
3.1、JSON概述
什么是JSON:
- JSON是一种数据格式
- XML也是一种数据格式
JSON格式表示两个学员信息的代码如下:
//JSON表达数据更简洁,更能够节约网络带宽
[{
sid:"s001",age:18},{
sid:"s002",age:19}]
XML格式表示两个学员信息的代码如下:
<students>
<student sid="s001">
<sname>jim</sname>
<age>18</age>
</student>
<student sid="s002">
<sname>tom</sname>
<age>19</age>
</student>
</students>
3.2、注意事项
-
客户端中params需要修改成:
data:
-
服务器获取参数值不再是
request.getParameter()...
而是:
StringBuffer stringBuffer = new StringBuffer(“”);
BufferedReader bufferedReader = request.getReader();
String str = null ;
while((str=bufferedReader.readLine())!=null){
stringBuffer.append(str);
}
str = stringBuffer.toString() ; -
我们会发现 str的内容如下:
{"uname":"lina","pwd":"ok"}
3.1、前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--引入vue.js文件-->
<script language="JavaScript" src="script/vue.js"></script>
<!--引入axios.min.js文件-->
<script language="JavaScript" src="script/axios.min.js"></script>
<script language="JavaScript">
window.onload=function(){
//文档就绪事件函数
var vue = new Vue({
el:"#div0",
data:{
uname:"lina",
pwd:"ok"
},
methods:{
axios02:function(){
axios({
method:"post",
url:"http://localhost:8080/Vue/axios02.do",
data:{
//注意:不能使用this.uname使能使用vue.uname,因为已经进入到axios中了,this代表的是axios
// 里面的属性,想要使用date中的属性只能通过vue来调用。
uname:vue.uname,
pwd:vue.pwd
}
})
.then(function (value) {
console.log(value);
})
.catch(function (reason) {
console.log(reason);
});
}
}
});
}
</script>
</head>
<body>
<div id="div0">
uname:<input type="text" v-model="uname"/><br/>
pwd:<input type="text" v-model="pwd"/><br/>
<input type="button" @click="axios02" value="发送JSON格式的参数值的异步请求"/>
</div>
</body>
</html>
3.2、后端代码
1) 加入Gson包
Gson是Google研发的一款非常优秀的JSON数据解析和生成工具
,它可以帮助我们将数据在JSON字符串和Java对象之间互相转换。
将jar包添加到类路径:Add as Library
2) User实体类
作用:封装json字符串转化为一个java对象后的数据。
package pojo;
public class User {
private String uname ;
private String pwd ;
public User(){
}
public User(String uname, String pwd) {
this.uname = uname;
this.pwd = pwd;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
@Override
public String toString() {
return "User{" +
"uname='" + uname + '\'' +
", pwd='" + pwd + '\'' +
'}';
}
}
3) Servlet代码
package axios;
import com.google.gson.Gson;
import pojo.User;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
@WebServlet("/axios02.do")//Servlet3.0使用注解代替原先的xml方式配置路径
public class Axios02Servlet extends HttpServlet {
private static final long serialVersionUID = -8499971529938553156L;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.创建StringBuffer对象来累加存储从请求体中读取到的每一行
StringBuffer stringBuffer = new StringBuffer("");
// 2.由于请求体数据有可能很大,所以Servlet标准在设计API的时候要求我们通过输入流来读取
BufferedReader bufferedReader = request.getReader();
// 3.声明临时变量
String str = null ;
// 4.循环读取
while((str=bufferedReader.readLine())!=null){
stringBuffer.append(str);
}
// 5.关闭流
bufferedReader.close();
// 6.累加的结果就是整个请求体
str = stringBuffer.toString() ;
System.out.println(str);// {"uname":"lina","pwd":"ok"} 获取到的是json字符串类型的数据
// 7.后台操作的是java对象,所以我们需要把json字符串转化为java对象
// 创建Gson对象:2种
// Gson gson =new GsonBuilder().create(); 这种方式功能更强大,eg:可以做格式化
Gson gson =new Gson();
// Gson有两个API:
// 1).fromJson(string,T) 将字符串转化成java object
// 2).toJson(java Object) 将java object转化成json字符串,这样才能响应给客户端
User user = gson.fromJson(str, User.class);
System.out.println(user);//User{uname='lina', pwd='ok'}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
P.S.:看着很麻烦是吧?别担心,将来我们有了SpringMVC之后,一个@RequestBody注解就能够搞定,非常方便!
4) 运行测试
P.S.:Chrome浏览器中将『请求负载』显示为英文:『Request Payload』。
4、服务器端返回JSON数据
说明:服务器端给客户端响应JSON格式的字符串,然后客户端需要将字符串转化成json对象,使用axios会自动把服务端响应给客户端的json字符串转化为json对象。
4.1、前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--引入vue.js文件-->
<script language="JavaScript" src="script/vue.js"></script>
<!--引入axios.min.js文件-->
<script language="JavaScript" src="script/axios.min.js"></script>
<script language="JavaScript">
window.onload=function(){
//文档就绪事件函数
var vue = new Vue({
el:"#div0",
data:{
uname:"lina",
pwd:"ok"
},
methods:{
axios03:function(){
axios({
method:"post",
url:"http://localhost:8080/Vue/axios03.do",
data:{
//注意:不能使用this.uname使能使用vue.uname,因为已经进入到axios中了,this代表的是axios
// 里面的属性,想要使用date中的属性只能通过vue来调用。
uname:vue.uname,
pwd:vue.pwd
}
})
.then(function (value) {
var data = value.data;
// data对应的数据:{uname:"鸠摩智",pwd:"ok"} ---->json对象
// 可以看出:会自动把服务端传来的json字符串转化为json对象,所以可以直接调用它的属性
vue.uname=data.uname;
vue.pwd=data.pwd;
//此处value中的data返回的是 js object,因此可以直接点出属性
//如果我们获取的是一个字符串: "{uname:\"鸠摩智\",pwd:\"ok\"}"
//js语言中 也有字符串和js对象之间互转的API
//string JSON.stringify(object) object->string
//object JSON.parse(string) string->object
})
.catch(function (reason) {
console.log(reason);
});
}
}
});
}
</script>
</head>
<body>
<div id="div0">
uname:<input type="text" v-model="uname"/><br/>
pwd:<input type="text" v-model="pwd"/><br/>
<input type="button" @click="axios03" value="发送JSON格式的参数值的异步请求,服务器端给客户端响应JSON格式的字符串"/>
</div>
</body>
</html>
4.2、后端代码
1) 加入Gson包
仍然需要Gson支持,不用多说
2) User实体类
略,这个地方是测试响应后的数据,没用到这个类,只不过现在页面流程是先发送请求在响应给页面数据,发送请求时json字符串转化为java对象时用到了。
3) Servlet代码
package axios;
import com.google.gson.Gson;
import pojo.User;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
@WebServlet("/axios03.do")//Servlet3.0使用注解代替原先的xml方式配置路径
public class Axios03Servlet extends HttpServlet {
private static final long serialVersionUID = -8499971529938553156L;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.创建StringBuffer对象来累加存储从请求体中读取到的每一行
StringBuffer stringBuffer = new StringBuffer("");
// 2.由于请求体数据有可能很大,所以Servlet标准在设计API的时候要求我们通过输入流来读取
BufferedReader bufferedReader = request.getReader();
// 3.声明临时变量
String str = null ;
// 4.循环读取
while((str=bufferedReader.readLine())!=null){
stringBuffer.append(str);
}
// 5.关闭流
bufferedReader.close();
// 6.累加的结果就是整个请求体
str = stringBuffer.toString() ;
System.out.println(str);// {"uname":"lina","pwd":"ok"} 获取到的是json字符串类型的数据
// 7.后台操作的是java对象,所以我们需要把json字符串转化为java对象
// 创建Gson对象:2种
// Gson gson =new GsonBuilder().create(); 这种方式功能更强大,eg:可以做格式化
Gson gson =new Gson();
// Gson有两个API:
// 1).fromJson(string,T) 将字符串转化成java object
// 2).toJson(java Object) 将java object转化成json字符串,这样才能响应给客户端
User user = gson.fromJson(str, User.class);
user.setUname("鸠摩智");
user.setPwd("123456");
System.out.println(user);//User{uname='lina', pwd='ok'}
//假设user是从数据库查询出来的,现在需要将其转化成json格式的字符串,然后响应给客户端
String userJsonStr = gson.toJson(user);//注意:转化后的是一个json字符串
response.setCharacterEncoding("UTF-8");
//MIME-TYPE 设置返回的类型是json
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(userJsonStr);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
4) 运行测试
流程:页面发送请求携带json格式的参数,之后在服务端获取并测试json字符串和java对象的转化,之修改下User实体类的数据便于看到页面效果,把json对象转化为json字符串返回给页面,客户端使用axios会自动把接收的json字符串转化为json对象,直接取值即可。把取出的值复制给了uname、pwd,这2个属性又绑定了文本框,所以点击提交按钮值会发生变化。
点击按钮前:
点击按钮后: