Ajax介绍
Ajax本身就是Asynchronous JavaScript And XML的缩写,直译为:异步的JavaScript和XML。
在实际应用中Ajax指的是:不刷新浏览器窗口,不做页面跳转,局部更新页面内容的技术。
『同步』和『异步』是一对相对的概念,那么什么是同步,什么是异步呢?
1. 同步和异步
1.1. 同步
多个操作按顺序执行,前面的操作没有完成,后面的操作就必须等待。所以同步操作通常是串行的。
1.2. 异步
多个操作相继开始并发执行,即使开始的先后顺序不同,但是由于它们各自是在自己独立的进程或线程中完成,所以互不干扰,谁也不用等谁。
2. 服务器渲染和Ajax渲染
2.1. 服务器渲染(整体渲染)
2.2. Ajax渲染(局部渲染)
在这里数据是通过Ajax方式以JSON格式来传递(Ajax渲染),可以实现页面无刷新地更新页面信息。
更多关于Ajax的基础知识参考链接:
原生Ajax:
- 菜鸟教程原生Ajax介绍和使用
基于JQuery的Ajax:
- W3school基于JQuery的Ajax介绍和使用
- Ajax与后台交互的几种方式
- Jquery ajax全解析
- Jquery Ajax总结
基于Axios的Ajax:
- Axios中文官网
与Ajax相关的前置知识博文:
- 前端传递数据的四种编码格式区别
JSON
什么是JSON?
JSON
(JavaScript Object Notation,JS对象标记)是一种前后端数据交换格式,其不是一种新的语言!- 其采用完全独立于编程语言的文本格式来存储和表示数据!
- 其具有简洁性和层次性,使得
JSON
成为理想的数据交换格式! - 其易于人阅读和编写,同时也易于机器解析和生成,能有效提升网络传输效率!
在JavaScript
语言中,一切都是对象。因此,任何JavaScript
支持的类型都可以通过JSON
来表示,
例如: 字符串, 数字, 对象, 数组等!
Json要求的语法格式?
- 对象表示为键值对,数据由逗号分割。
- 花括号【大括号】保存对象
- 方括号【中括号】保存数组
JSON键值对
是用来保存JavaScript对象
的一种方式,其和JavaScript
对象的写法也大同小异.
键/值对组合中的键名写在前面并用双引号
""
包裹,键值之间用:
分隔,然后紧接着值,值也要用""
进行包裹!!
示例JSON
{"name":"Carson"}
{"age":"3"}
{"sex":"男"}
JSON和JavaScript对象的关系?
JSON
是JavaScript对象的字符串表示法
,它使用文本表示一个JS对象的信息,本质是一个字符串
//这是一个JS对象,注意其键名也是可以使用双引号包裹的就变成了JSON对象
var obj = {a:"hello",b:"world"};
var json = '{"a":"hello","b":"world"}';//这是一个json字符串,本质就是一个字符串
JSON对象和JSON字符串的对比
- JSON对象是直接可以使用JQuery操作的格式,如C#中可以用对象(类名)点出属性(方法)一样
- JSON字符串仅仅只是一个字符串,一个整体,不截取的话没办法取出其中存储的数据,不能直接使用
JSON对象:
var str2 = { "name": carson", "sex": "man" };
JSON字符串:
var str1 = '{ "name": "deyuyi", "sex": "man" }';
JSON字符串和JavaScript对象转换
-
要实现
JSON字符串
转换为JavaScript对象
,使用:JSON.parse()
方法var obj = JSON.parse('{"a":"hello","b":"world"}'); //结果是: {a:"hello",b:"world"};
-
要实现从
JavaScript对象
转换为JSON字符串
,使用JSON.stringify()
方法var json = JSON.stringify({a:"hello",b:"world"}); //结果是: '{"a":"hello","b":"world"}'
-
JSON类是JavaScript中自带的类!
Axios
1. Axios的简介
为什么不使用JQuery框架实现AJax?
- jQuery操作Dom太频繁,所以少用JQuery。
为什么使用Axios?
-
使用原生的JavaScript程序执行Ajax极其繁琐,所以一定要使用框架来完成。
-
Vue.js并不包含AJAX的通信功能, 为了解决通信问题, 作者推荐使用Axios框架解决通信问题。
-
而Axios就是目前最流行的前端Ajax框架。
Axios官网:http://www.axios-js.com/
想要使用Axios,需要先有相应的axios库,有两种引用axios库的方式:
- 导入对应的js文件: 官方提供的script标签引入方式为:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
- 或者我们也可以把这个axios.min.js文件下载下来保存到本地使用。
2. Axios的基本用法(以Maven示例)
2.1. 在前端页面引入开发环境
- 可以直接在web资源包中新建一个static包,并导入axios和vue库在本地使用。
接着在相应的html页面中,引入axios和vue库。
<script type="text/javascript" src="/web应用名/static/vue.js"></script>
<script type="text/javascript" src="/web应用名/static/axios.min.js"></script>
- 也可以使用script标签+链接方式,直接引入axios库和vue库。
直接在相应的html页面中直接引入:
<!--引入vue和 axios框架-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"> </script>
2.2. 发送普通的异步请求(不使用JSON格式)
前端:
前端代码(Vue+axios结合)
:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head><!--Axios是一个开源的可以用在浏览器和NodeJS的异步通信框架,-->
<!--其主要作用就是实现Ajax的异步通信--><body><div id="app"><!--@click是vue绑定dom事件的简写形式,对应的属性名是处理dom事件的事件处理函数,这里的函数加不加()都可以--><button @click="commonParam">普通异步请求</button><!--v-text是vue中用于操作纯文本的指令,它会替代显示对应的数据对象上的值。--><span v-text="message"></span></div><!--引入vue和 axios框架--><script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script><script src="https://unpkg.com/axios/dist/axios.min.js"> </script><script>var app = new Vue({el:"#app",data:{"message":""},methods:{commonParam:function () {//使用axios发起异步请求axios({//使用post请求method:"post",//url前面需要加web应用名,这里是axios_servleturl:"/axios_servlet/servletDemo01",//携带普通请求参数//这里是post请求的特殊用法使用了params参数传递,post请求有params参数传递和data参数传递//params是会将请求参数添加到url中且参数以字符串形式进行传参,一般用于get请求(且get请求中只有param选项,不存在data这个选项)。params:{username:"Carson",password:"123456"}}).then(response=>{//then里面是处理请求成功的响应数据//response就是服务器端的响应数据,是json类型的//response里面的data就是响应体的数据this.message = response.data}).catch(error=>{//error是请求失败的错误描述//error.response就是请求失败时候的响应信息console.log(error.response)})}}})</script></body>
</html>
Axios程序接收到的响应数据的对象结构
即响应数据对象response的属性。
属性名 | 作用 |
---|---|
config | 调用axios(config对象)方法时传入的JSON对象 |
data | 服务器端返回的响应体数据 |
headers | 响应消息头 |
request | 原生JavaScript执行Ajax操作时使用的XMLHttpRequest |
status | 响应状态码 |
statusText | 响应状态码的说明文本 |
后端:
pom.xml中加入servlet依赖
<!--servlet依赖--><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version></dependency>
后端servlet代码:
package com.carson.servlet;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class ServletDemo01 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//防止乱码request.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=UTF-8");//接收请求参数的username和passwordString username = request.getParameter("username");String password = request.getParameter("password");System.out.println("异步接收到的username是:"+username+" password是:"+password);//向浏览器响应数据response.getWriter().write("hello,axios的普通字符串参数的异步请求!!");//测试异常//int num = 10/0;}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}
配置tomcat和tomcat启动路径:
web.xml
中注册servlet和配置servlet映射路径:
<!--注册servlet--><servlet><servlet-name>servletDemo01</servlet-name><servlet-class>com.carson.servlet.ServletDemo01</servlet-class></servlet><servlet-mapping><servlet-name>servletDemo01</servlet-name><url-pattern>/servletDemo01</url-pattern></servlet-mapping>
效果:
可以看到,哪怕我们现在用的是POST请求方式,所有请求参数都被放到URL地址后面了。
正常的话请求参数是位于请求体中的,但这里是Post请求的特殊用法,在使用axios时使用了param参数定义请求参数,即:
而如果还想保留原来的将请求参数保留在请求体中而不是url中,使用axios时需要使用data选项来定义请求参数即可,即:
2.3. 发送JSON异步请求(使用JSON格式)
前端
前端代码(vue和axios的结合)
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head><!--Axios是一个开源的可以用在浏览器和NodeJS的异步通信框架,-->
<!--其主要作用就是实现Ajax的异步通信--><body>
<div id="app"><!--@click是vue绑定dom事件的简写形式,对应的属性名是处理dom事件的事件处理函数,这里的函数加不加()都可以--><button @click="sendJsonBody()">Json数据的异步请求</button><!--v-text是vue中用于操作纯文本的指令,它会替代显示对应的数据对象上的值。--><span v-text="message"></span></div><!--引入vue和 axios框架-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"> </script><script>var app = new Vue({el:"#app",data:{"message":""},methods:{sendJsonBody:function () {//使用axios发送异步请求,要携带Json请求体的参数axios({//使用post请求method:"post",//url前面需要加web应用名,这里是axios_servleturl:"/axios_servlet/servletDemo02",//携带Json请求体参数//data是将请求参数添加到请求体(body)中且参数以json格式传参,用于post请求。data:{userName:"Carson",userPwd:"88888888"}}).then(response=>{this.message = response.data}).catch(error=>{//error是请求失败的错误描述//error.response就是请求失败时候的响应信息console.log(error.response)})}}})
</script></body>
</html>
后端:
1.pom.xml
加入GSON依赖。
Gson是Google研发的一款非常优秀的JSON数据解析和生成工具,它可以帮助我们将数据在JSON字符串和Java对象之间互相转换。
<!-- 谷歌的json解析和生成依赖 --><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.2.4</version></dependency>
使用maven为开发环境时,由于GSON依赖的特殊性,即使pom.xml
中已经配置了GSON依赖,但是在tomcat的lib目录
中也要加入GSON依赖,否则启动tomcat时会找不到这个依赖:
2.测试用的实体类User.java
package com.carson.pojo;public class User {private String userName;private String userPwd;public User() {}public User(String userName, String userPwd) {this.userName = userName;this.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;}@Overridepublic String toString() {return "User{" +"userName='" + userName + '\'' +", userPwd='" + userPwd + '\'' +'}';}
}
3:后端servlet代码:
package com.carson.servlet;import com.carson.pojo.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;public class ServletDemo02 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {try{//防止乱码request.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=UTF-8");//我们要获取json请求体的参数,其实就是将json请求体的参数封装到User对象中//1. 获取Json请求体的内容(获取请求体的参数需要使用getReader()方法,其是对getInputStream()方法的二次封装,便于读取字符)BufferedReader requestReader = request.getReader();//2. 从requestReader中循环读取拼接字符串StringBuilder stringBuilder = new StringBuilder();String buffer = "";while((buffer=requestReader.readLine())!=null){stringBuilder.append(buffer);}//3. 将stringBuilder转成String字符串,这个字符串就是Json请求体String jsonBody = stringBuilder.toString();//4. 将jsonBody通过Gson解析转成User对象Gson gson = new Gson();User user = gson.fromJson(jsonBody,User.class);System.out.println("user是:"+user);System.out.println("客户端传入的参数userName的值为:" + user.getUserName() + ",传入的userPwd的值为:" + user.getUserPwd());//在实际开发中服务器端向客户端响应的99%都会是Json字符串User responseUser = new User("Jay Chow","ggggggg");//将responseUser转成json字符串String responseJson = gson.toJson(responseUser);//向浏览器响应数据response.getWriter().write(responseJson);}catch (Exception e){e.printStackTrace();}}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request,response);}
}
3: tomcat的启动路径不变,这里仍然为上面配置的: /axios_servlet
.
4: web.xml
中注册servlet和配置servlet映射路径:
<servlet><servlet-name>servletDemo02</servlet-name><servlet-class>com.carson.servlet.ServletDemo02</servlet-class>
</servlet>
<servlet-mapping><servlet-name>servletDemo02</servlet-name><url-pattern>/servletDemo02</url-pattern>
</servlet-mapping>
效果:
可以看到,由于使用axios时使用data选项定义请求参数:
请求参数不再位于url中,而是位于请求体中。
3. . 封装Json工具类简化Axios异步交互
3.1. jackson的使用介绍
3.1.1. jackson的简介
jackson
是Java中比较常用的JSON解析的工具包,SpringMVC
和SpringBoot
中默认支持的就是jackson.
Jackson应该是目前比较好的json解析工具了, 当然工具不止这一个,比如还有阿里巴巴的 fastjson
等等
3.1.2. jackson的使用
第一步: 引入jar包
pom.xml中加入依赖:
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.9.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.9.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.8</version>
</dependency>
同样,由于这几个依赖的特殊性,也需要在tomcat的lib目录中加入。
第二步: API介绍
-
创建ObjectMapper对象
ObjectMapper objectMapper = new ObjectMapper();
-
调用
objectMapper.writeValueAsString(obj)
方法将java对象转成json字符串 -
调用
objectMapper.readValue(text, Class);
将json字符串转成java对象 -
将
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);
3.2. 封装Json工具类用于获取json格式的请求参数以及向客户端响应json字符串
3.2.1. JsonUtils工具类
package com.carson.utils;import com.fasterxml.jackson.databind.ObjectMapper;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;public class JsonUtils {/*** 获取Json请求体的参数,并且返回封装了参数的JavaBean对象* @param request* @param clazz* @return*/public static Object parseJsonToBean(HttpServletRequest request, Class clazz){try {BufferedReader reader = request.getReader();StringBuffer stringBuffer = new StringBuffer("");String line = "";while ((line=reader.readLine()) != null){stringBuffer.append(line);}//此时拿到的还只是那个Json字符串String jsonBody = stringBuffer.toString();//我们还需要从Json字符串中解析出每一个key对应的值//其实就是将Json字符串转换成JavaBean对象,然后Json字符串中的数据就存储到了JavaBean对象中,然后就能从JavaBean对象中获取数据//使用jacksonreturn new ObjectMapper().readValue(jsonBody, clazz);} catch (Exception e) {e.printStackTrace();throw new RuntimeException(e.getMessage());}}/*** 将对象转成Json字符串响应给前端* @param response* @param object*/public static void parseObjectToJson(HttpServletResponse response, Object object){try {//将对象转成Json字符串String jsonStr = new ObjectMapper().writeValueAsString(object);//再将Json字符串响应给前端response.getWriter().write(jsonStr);} catch (Exception e) {e.printStackTrace();throw new RuntimeException(e.getMessage());}}
}
3.2.2. 利用JsonUtils获取json格式的请求参数以及向客户端响应json字符串
前端:
前端代码:(vue和axios的结合)
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head><!--Axios是一个开源的可以用在浏览器和NodeJS的异步通信框架,-->
<!--其主要作用就是实现Ajax的异步通信--><body>
<div id="app"><button @click="sendJsonBody()">使用JsonUtils的异步请求</button><span v-text="message"></span></div><!--引入vue和 axios框架-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"> </script><script>var vue = new Vue({el:"#app",data:{"message":""},methods:{sendJsonBody(){//使用axios发送异步请求,要携带Json请求体的参数axios({method:"post",url:"/axios_servlet/servletDemo03",//携带Json请求体参数data:{"userName":"aobama","userPwd":"999999"}}).then(response => {console.log(response.data.resultFlag)console.log(response.data.resultData)console.log(response.data.msg)this.message = response.data.resultData})}}})
</script>
</body>
</html>
后端
后端servlet代码:
package com.carson.servlet;import com.carson.pojo.User;
import com.carson.utils.JsonUtils;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.util.HashMap;
import java.util.Map;public class ServletDemo03 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {try {//防止乱码request.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=UTF-8");//获取Json请求体的参数,并且封装到User对象中User user = (User) JsonUtils.parseJsonToBean(request, User.class);System.out.println("userName=" + user.getUserName() + ", userPwd=" + user.getUserPwd());//封装需要响应给客户端的数据Map responseMap = new HashMap();responseMap.put("resultFlag", true);responseMap.put("resultData","hello from ServletDemo03!");responseMap.put("msg", "hello world!");//将响应数据转为Json,并向浏览器响应数据JsonUtils.parseObjectToJson(response, responseMap);} catch (Exception e) {e.printStackTrace();}}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}
tomcat的启动路径不变,这里仍然为上面配置的: /axios_servlet
.
web.xml
中注册servlet和配置servlet映射路径:
<servlet><servlet-name>servletDemo03</servlet-name>
<servlet-class>com.carson.servlet.ServletDemo03</servlet-class></servlet>
<servlet-mapping><servlet-name>servletDemo03</servlet-name><url-pattern>/servletDemo03</url-pattern>
</servlet-mapping>
效果:
创作不易!!欢迎关注个人公众号!!获取更多知识内容!!