Ajax本身就是Asynchronous JavaScript And XML的缩写,直译为:异步的JavaScript和XML。
在实际应用中Ajax指的是:不刷新浏览器窗口,不做页面跳转,局部更新页面内容的技术。
『同步』和『异步』是一对相对的概念,那么什么是同步,什么是异步呢?
多个操作按顺序执行,前面的操作没有完成,后面的操作就必须等待。所以同步操作通常是串行的。
多个操作相继开始并发执行,即使开始的先后顺序不同,但是由于它们各自是在自己独立的进程或线程中完成,所以互不干扰,谁也不用等谁。
在这里数据是通过Ajax方式以JSON格式来传递(Ajax渲染),可以实现页面无刷新地更新页面信息。
更多关于Ajax的基础知识参考链接:
原生Ajax:
基于JQuery的Ajax:
基于Axios的Ajax:
与Ajax相关的前置知识博文:
什么是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对象:
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中自带的类!
为什么不使用JQuery框架实现AJax?
为什么使用Axios?
使用原生的JavaScript程序执行Ajax极其繁琐,所以一定要使用框架来完成。
Vue.js并不包含AJAX的通信功能, 为了解决通信问题, 作者推荐使用Axios框架解决通信问题。
而Axios就是目前最流行的前端Ajax框架。
Axios官网:http://www.axios-js.com/
想要使用Axios,需要先有相应的axios库,有两种引用axios库的方式:
<script src="https://unpkg.com/axios/dist/axios.min.js">script>
接着在相应的html页面中,引入axios和vue库。
<script type="text/javascript" src="/web应用名/static/vue.js">script>
<script type="text/javascript" src="/web应用名/static/axios.min.js">script>
直接在相应的html页面中直接引入:
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js">script>
<script src="https://unpkg.com/axios/dist/axios.min.js"> script>
前端:
前端代码(Vue+axios结合)
:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div id="app">
<button @click="commonParam">普通异步请求button>
<span v-text="message">span>
div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/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_servlet
url:"/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依赖
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>4.0.1version>
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 {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//防止乱码
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//接收请求参数的username和password
String 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;
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
web.xml
中注册servlet和配置servlet映射路径:
<servlet>
<servlet-name>servletDemo01servlet-name>
<servlet-class>com.carson.servlet.ServletDemo01servlet-class>
servlet>
<servlet-mapping>
<servlet-name>servletDemo01servlet-name>
<url-pattern>/servletDemo01url-pattern>
servlet-mapping>
效果:
可以看到,哪怕我们现在用的是POST请求方式,所有请求参数都被放到URL地址后面了。
正常的话请求参数是位于请求体中的,但这里是Post请求的特殊用法,在使用axios时使用了param参数定义请求参数,即:
而如果还想保留原来的将请求参数保留在请求体中而不是url中,使用axios时需要使用data选项来定义请求参数即可,即:
前端
前端代码(vue和axios的结合)
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div id="app">
<button @click="sendJsonBody()">Json数据的异步请求button>
<span v-text="message">span>
div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/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_servlet
url:"/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对象之间互相转换。
<dependency>
<groupId>com.google.code.gsongroupId>
<artifactId>gsonartifactId>
<version>2.2.4version>
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;
}
@Override
public 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 {
@Override
protected 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();
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
}
3: tomcat的启动路径不变,这里仍然为上面配置的:/axios_servlet
.
4: web.xml
中注册servlet和配置servlet映射路径:
<servlet>
<servlet-name>servletDemo02servlet-name>
<servlet-class>com.carson.servlet.ServletDemo02servlet-class>
servlet>
<servlet-mapping>
<servlet-name>servletDemo02servlet-name>
<url-pattern>/servletDemo02url-pattern>
servlet-mapping>
效果:
可以看到,由于使用axios时使用data选项定义请求参数:
请求参数不再位于url中,而是位于请求体中。
jackson
是Java中比较常用的JSON解析的工具包,SpringMVC
和SpringBoot
中默认支持的就是jackson.
Jackson应该是目前比较好的json解析工具了, 当然工具不止这一个,比如还有阿里巴巴的 fastjson
等等
pom.xml中加入依赖:
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-annotationsartifactId>
<version>2.9.8version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-coreartifactId>
<version>2.9.8version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.9.8version>
dependency>
同样,由于这几个依赖的特殊性,也需要在tomcat的lib目录中加入。
创建ObjectMapper对象 ObjectMapper objectMapper = new ObjectMapper();
调用objectMapper.writeValueAsString(obj)
方法将java对象转成json字符串
调用objectMapper.readValue(text, Class);
将json字符串转成java对象
将json数组
转成List
//1.创建ObjectMapper对象
ObjectMapper objectMapper = new ObjectMapper();
//2.调用readValue()
TypeReference<List<Bean>> ref = new TypeReference<List<Bean>>(){};
List<Bean> list = objectMapper.readValue(jsonStr, ref);
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对象中获取数据
//使用jackson
return 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());
}
}
}
前端:
前端代码:(vue和axios的结合)
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div id="app">
<button @click="sendJsonBody()">使用JsonUtils的异步请求button>
<span v-text="message">span>
div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/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 {
@Override
protected 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();
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
tomcat的启动路径不变,这里仍然为上面配置的:/axios_servlet
.
web.xml
中注册servlet和配置servlet映射路径:
<servlet>
<servlet-name>servletDemo03servlet-name>
<servlet-class>com.carson.servlet.ServletDemo03servlet-class>
servlet>
<servlet-mapping>
<servlet-name>servletDemo03servlet-name>
<url-pattern>/servletDemo03url-pattern>
servlet-mapping>
创作不易!!欢迎关注个人公众号!!获取更多知识内容!!