Ajax&Axios
一、Ajax
1. 目标
- 了解服务器渲染和Ajax渲染的区别
- 了解同步和异步的区别
2. 内容
2.1 服务器端渲染
2.2 Ajax渲染(局部更新)
2.3 前后端分离
真正的前后端分离是前端项目和后端项目分服务器部署,在这里先理解为彻底舍弃服务器端渲染,数据全部通过Ajax方式以JSON格式来传递
2.4 同步与异步
Ajax本身就是Asynchronous JavaScript And XML的缩写,直译为:异步的JavaScript和XML。在实际应用中Ajax指的是:不刷新浏览器窗口,不做页面跳转,局部更新页面内容的技术。
『同步』和『异步』是一对相对的概念,那么什么是同步,什么是异步呢?
2.4.1 同步
多个操作按顺序执行,前面的操作没有完成,后面的操作就必须等待。所以同步操作通常是串行的。
2.4.2 异步
多个操作相继开始并发执行,即使开始的先后顺序不同,但是由于它们各自是在自己独立的进程或线程中完成,所以互不干扰,谁也不用等谁。
第二章 Axios
1.目标
- 了解Axios
- 掌握Axios发送异步请求
- 掌握Axios携带json类型的请求参数
- 掌握服务器端返回json数据
2. 内容
2.1 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文件下载下来保存到本地来使用。
2.2 Axios基本用法
2.2.1 在前端页面引入开发环境
<script type="text/javascript" src="/demo/static/vue.js"></script>
<script type="text/javascript" src="/demo/static/axios.min.js"></script>
2.2.2 发送普通请求参数
2.2.2.1 前端代码
HTML标签:
<div id="app">
<button @click="commonParam">普通请求参数</button>
</div>
Vue+axios代码:
var vue = new Vue({
"el":"#app",
"data":{
"message":""
},
"methods":{
commonParam(){
//使用axios发送异步请求
axios({
"method":"post",
"url":"demo01",
"params":{
"userName":"tom",
"userPwd":"123456"
}
}).then(response => {
//then里面是处理请求成功的响应数据
//response就是服务器端的响应数据,是json类型的
//response里面的data就是响应体的数据
this.message = response.data
}).catch(error => {
//error是请求失败的错误描述
//error.response就是请求失败时候的响应信息
console.log(error.response)
})
}
}
})
</script>
效果:所有请求参数都被放到URL地址后面了,哪怕现在用的是POST请求方式。
2.2.2.2 后端代码
package com.aqrlmy.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author Leevi
* 日期2021-05-21 09:15
*/
public class ServletDemo01 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//1. 接收请求参数userName和userPwd
String userName = request.getParameter("userName");
String userPwd = request.getParameter("userPwd");
System.out.println(userName + ":" + userPwd);
//模拟出现异常
//int num = 10/0;
//2. 向浏览器响应数据
response.getWriter().write("hello world!!!");
}
}
2.2.3 axios程序接收到的响应对象结构
属性名 | 作用 |
---|---|
config | 调用axios(config对象)方法时传入的JSON对象 |
data | 服务器端返回的响应体数据 |
headers | 响应消息头 |
request | 原生JavaScript执行Ajax操作时使用的XMLHttpRequest |
status | 响应状态码 |
statusText | 响应状态码的说明文本 |
2.2.4 服务器端处理请求失败后
catch(error => { // catch()服务器端处理请求出错后,会调用
console.log(error); // error就是出错时服务器端返回的响应数据
console.log(error.response); // 在服务器端处理请求失败后,获取axios封装的JSON格式的响应数据对象
console.log(error.response.status); // 在服务器端处理请求失败后,获取响应状态码
console.log(error.response.statusText); // 在服务器端处理请求失败后,获取响应状态说明文本
console.log(error.response.data); // 在服务器端处理请求失败后,获取响应体数据
});
在给catch()函数传入的回调函数中,error对象封装了服务器端处理请求失败后相应的错误信息。其中,axios封装的响应数据对象,是error对象的response属性。response属性对象的结构如下图所示:
可以看到,response对象的结构还是和then()函数传入的回调函数中的response是一样的:
回调函数:开发人员声明,但是调用时交给系统来调用。像单击响应函数、then()、catch()里面传入的都是回调函数。回调函数是相对于普通函数来说的,普通函数就是开发人员自己声明,自己调用:
function sum(a, b) { return a+b; } var result = sum(3, 2); console.log("result="+result);
2.3 发送请求体JSON
2.3.1 前端代码
HTML代码:
<button @click="sendJsonBody()">请求体JSON</button>
Vue+axios代码:
<script>
var vue = new Vue({
"el":"#app",
"data":{
"message":""
},
"methods":{
sendJsonBody(){
//使用axios发送异步请求,要携带Json请求体的参数
axios({
"method":"post",
"url":"demo01",
//携带Json请求体参数
"data":{
"userName":"aobama",
"userPwd":"999999"
}
}).then(response => {
this.message = response.data
})
}
}
})
</script>
2.3.2 后端代码
2.3.2.1 加入Gson包
Gson是Google研发的一款非常优秀的JSON数据解析和生成工具,它可以帮助我们将数据在JSON字符串和Java对象之间互相转换。
2.3.2.2 User类
package com.aqrlmy.bean;
/**
* 包名:com.aqrlmy.bean
*
* @author Leevi
* 日期2021-06-16 10:11
*/
public class User {
private String userName;
private String userPwd;
public User() {
}
public User(String userName, String userPwd) {
this.userName = userName;
this.userPwd = userPwd;
}
@Override
public String toString() {
return "User{" +
"userName='" + userName + '\'' +
", userPwd='" + userPwd + '\'' +
'}';
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
}
2.3.2.3 Servlet代码
package com.aqrlmy.servlet;
import com.aqrlmy.bean.User;
import com.google.gson.Gson;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
/**
* @author Leevi
* 日期2021-06-16 09:12
*/
public class ServletDemo01 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
response.setContentType("text/html;charset=UTF-8");
//request.getParameter(name),request.getParameterValues(name),request.getParameterMap()这仨方法只能获取普通参数
//什么是普通参数:1. 地址后面携带的参数 2. 表单提交的参数
/*String userName = request.getParameter("userName");
String userPwd = request.getParameter("userPwd");
System.out.println("客户端传入的参数userName的值为:" + userName + ",传入的userPwd的值为:" + userPwd);*/
//要获取Json请求体的参数,就必须得进行Json解析:可用来做Json解析的工具jar包有gson、fastjson、jackson(SpringMVC以及SpringBoot默认支持的)
//做json解析其实就是:1. 将Java对象转成json字符串 2. 将json字符串转成Java对象
//要获取json请求体的参数,其实就是将json请求体的参数封装到User对象中
//1. 获取Json请求体的内容
BufferedReader requestReader = request.getReader();
//2. 从requestReader中循环读取拼接字符串
StringBuilder stringBuilder = new StringBuilder();
String buffer = "";
while ((buffer = requestReader.readLine()) != null) {
stringBuilder.append(buffer);
}
//3. 将stringBuilder转成字符串,这个字符串就是Json请求体
String jsonBody = stringBuilder.toString();
//4. 将jsonBody通过Json解析转成User对象
Gson gson = new Gson();
User user = gson.fromJson(jsonBody, User.class);
System.out.println("客户端传入的参数userName的值为:" + user.getUserName() + ",传入的userPwd的值为:" + user.getUserPwd());
//模拟服务器出现异常
//int num = 10/0;
response.getWriter().write("你好世界");
} catch (Exception e) {
e.printStackTrace();
}
}
}
P.S.:看着很麻烦是吧?别担心,有了SpringMVC之后,一个@RequestBody注解就能够搞定,非常方便!
2.4 服务器端返回JSON数据
2.4.1 前端代码
sendJsonBody(){
//使用axios发送异步请求,要携带Json请求体的参数
axios({
"method":"post",
"url":"demo01",
//携带Json请求体参数
"data":{
"userName":"aobama",
"userPwd":"999999"
}
}).then(response => {
//目标是获取响应数据中的用户的用户名或者密码
this.message = response.data.userName
})
}
2.4.2 后端代码
2.4.2.1 加入Gson包
仍然需要Gson支持,不用多说
2.4.2.2 Servlet代码
package com.aqrlmy.servlet;
import com.aqrlmy.bean.User;
import com.google.gson.Gson;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
/**
* @author Leevi
* 日期2021-06-16 09:12
*/
public class ServletDemo01 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
response.setContentType("text/html;charset=UTF-8");
//request.getParameter(name),request.getParameterValues(name),request.getParameterMap()这仨方法只能获取普通参数
//什么是普通参数:1. 地址后面携带的参数 2. 表单提交的参数
/*String userName = request.getParameter("userName");
String userPwd = request.getParameter("userPwd");
System.out.println("客户端传入的参数userName的值为:" + userName + ",传入的userPwd的值为:" + userPwd);*/
//要获取Json请求体的参数,就必须得进行Json解析:可用来做Json解析的工具jar包有gson、fastjson、jackson(SpringMVC以及SpringBoot默认支持的)
//做json解析其实就是:1. 将Java对象转成json字符串 2. 将json字符串转成Java对象
//要获取json请求体的参数,其实就是将json请求体的参数封装到User对象中
//1. 获取Json请求体的内容
BufferedReader requestReader = request.getReader();
//2. 从requestReader中循环读取拼接字符串
StringBuilder stringBuilder = new StringBuilder();
String buffer = "";
while ((buffer = requestReader.readLine()) != null) {
stringBuilder.append(buffer);
}
//3. 将stringBuilder转成字符串,这个字符串就是Json请求体
String jsonBody = stringBuilder.toString();
//4. 将jsonBody通过Json解析转成User对象
Gson gson = new Gson();
User user = gson.fromJson(jsonBody, User.class);
System.out.println("客户端传入的参数userName的值为:" + user.getUserName() + ",传入的userPwd的值为:" + user.getUserPwd());
//模拟服务器出现异常
//int num = 10/0;
//服务器端向客户端响应普通字符串
//response.getWriter().write("你好世界");
//在实际开发中服务器端向客户端响应的99%都会是Json字符串
User responseUser = new User("周杰棍","ggggggg");
//将responseUser转成json字符串
String responseJson = gson.toJson(responseUser);
response.getWriter().write(responseJson);
} catch (Exception e) {
e.printStackTrace();
}
}
}
2.5 jackson的使用介绍
2.5.1 jackson的简介
jackson是Java中比较常用的JSON解析的工具包,SpringMVC和SpringBoot中默认支持的就是jackson
2.5.2 jackson的使用
第一步: 引入jar包
第二步: API介绍
-
创建ObjectMapper对象
ObjectMapper objectMapper = new ObjectMapper();
-
调用
writeValueAsString(obj)
方法将对象转成json字符串 -
调用
mapper.readValue(text, Class);
将json字符串转成对象 -
将
json数组
转成List<Bean>
//1.创建ObjectMapper对象 ObjectMapper objectMapper = new ObjectMapper(); //2.调用readValue() TypeReference<List<Bean>> ref = new TypeReference<List<Bean>>(){}; List<Bean> list = objectMapper.readValue(jsonStr, ref);
2.6 封装Json工具类用于获取json格式的请求参数以及向客户端响应json字符串
package com.aqrlmy.utils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
/**
* 包名:com.aqrlmy.utils
*
* @author Leevi
* 日期2021-05-21 10:23
*/
public class JsonUtils {
/**
* 获取客户端传递的json类型的请求参数,并且转成JavaBean对象
* @param request
* @param tClass
* @return
*/
public static Object parseJsonToBean(HttpServletRequest request, Class<? extends Object> tClass) {
//请求体的数据就在BufferReader里面
BufferedReader bufferedReader = null;
try {
//1. 获取请求参数:如果是普通类型的请求参数"name=value&name=value"那么就使用request.getXXX()
//如果是json请求体的参数,则需要进行json解析才能获取
bufferedReader = request.getReader();
StringBuilder stringBuilder = new StringBuilder();
String body = "";
while ((body = bufferedReader.readLine()) != null) {
stringBuilder.append(body);
}
//目标:将json里面的数据封装到JavaBean里面:这就叫json解析
ObjectMapper objectMapper = new ObjectMapper();
Object Object = objectMapper.readValue(stringBuilder.toString(), tClass);
return Object;
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
} finally {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
}
/**
* 将对象转成json字符串并且响应到客户端
* @param response
* @param object
*/
public static void writeResult(HttpServletResponse response,Object object){
try {
ObjectMapper objectMapper = new ObjectMapper();
String jsonStr = objectMapper.writeValueAsString(object);
response.getWriter().write(jsonStr);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
}