什么是ajax
Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指⼀种创建交互式网页应用的网页开发技术。
通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
传统的网页(不使用Ajax)如果需要更新内容,必须重新加载
整个网页页面。
缺点
todo 这个场景暂时无法还原,先不进行八股的背诵,先看看,等遇到该场景再说吧
ajax 只能实现局部刷新,无法执行整体的页面跳转并携带数据。
ajax就是为了实现局部刷新,但有些场景忘了这回事儿的话,就是个坑。
同步与异步
-
异步请求
可以进行局部请求,整个页面不会刷新,进行数据的交互。客户端请求到服务器,如果服务器没有响应,客户端可以自由活动。
异步的效率更高
-
同步请求
请求时,整个页面会进行加载,地址栏一般也会发生变化。客户端请求到服务器,如果服务器没有响应,客户端只能等待,卡死
以下面的图片举例,
- 如果是异步请求,在等待响应的时候,仍然可以操作输入框
- 如果是同步请求,在等待响应的时候,不可以操作输入框
使用场景
- 用户注册 校验用户名。
- 搜索框中的提示。
什么时候用同步
在时序性较强的要求下使用同步,比如说一个函数需要另一个函数返回的值,使用异步就有可能得不到该值。
例如提交订单、提交用户信息这种操作上。
ajax
Ajax
存在于浏览器端的技术。一种用户交互数据的方式。
AJAX出现的目的
在不刷新页面的前提下,也可以跟服务器进行通信,从而根据服务器响应的信息,再根据js代码完成动态内容变化。
ajax原理
- A 异步的 asynchronous
- J JavaScript
- A AND
- X XML — text json
X 代表数据的格式,XML规范,但重量级(需要定义规范的标签),现在常用的是json数据格式
ajax引擎
存在于浏览器端, 异步请求的核心就是ajax引擎。
js基于对象语言,js中就存在这么一个类型对象XMLHttpRequest
----ajax引擎!
XMLHttpRequest就是异步请求的对象,发送ajax请求的时候需要访问XMLHttpRequest对象。
同步请求:例如在浏览器端录入username,通过浏览器把请求整个发送给服务器,服务器端再把响应回来的数据整个发送给浏览器端,页面需要重新加载一遍
。
ajax异步请求:每个浏览器上都有一个ajax引擎,ajax引擎帮你发送局部请求,ajax发送请求的时候不会影响页面中的其他操作,ajax发送数据到服务器,服务器处理后把数据响应到ajax引擎,ajax引擎其实在js
中,js会在浏览器端完成动态的操作。
js中原生的异步请求操作(了解)
- 创建AJAX引擎对象 XMLHttpRequest。
- 完成回调函数,当服务器响应成功之后会自动调用的函数。
用于监听ajax引擎对象的状态,主要监听响应成功的之后!! - 确认请求路径与方式。
- 发送请求。
package com.lx.servlet.ajaxTest;
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;
@WebServlet("/ajaxTest")
public class AjaxTest extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("hello ajax");
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>原生的js异步请求</title>
</head>
<body>
<input type="button" value="发送异步请求" onclick="fun()">
<div id="myDiv"></div>
</body>
<script type="text/javascript">
// 发送ajax异步请求
function fun() {
// 1. 创建ajax引擎对象
var httpRequest = new XMLHttpRequest();
// 2. 监听ajax请求对象 主要监听响应成功后的操作
httpRequest.onreadystatechange = function () {
// 如果请求对象的状态发生改变 就会触发该函数
// 只判断成功响应信息
if(httpRequest.readyState == 4 && httpRequest.status == 200){
// alert(httpRequest.responseText)
document.getElementById("myDiv").innerText = httpRequest.responseText
}
}
// 3. 发送请求的方式和接收方
// 第三个参数为是否异步,true 异步
httpRequest.open("get","/ajaxTest",true)
// 4. 发送请求
httpRequest.send()
}
</script>
</html>
jquery中的ajax请求
$.get() $.post()
package com.lx.servlet.ajaxTest;
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;
@WebServlet("/jqueryAsynGet")
public class AjaxTest extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name");
System.out.println(name);
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().write(name);
}
}
// springboot版本
package com.example.javasestudy;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@CrossOrigin
@RestController
public class AjaxStudy {
@GetMapping("ajaxStudy")
public String ajaxStudy(@RequestParam("name") String name){
return name;
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>测试ajax</title>
<script type="text/javascript" src="js/jquery-1.12.4.js"></script>
</head>
<body>
<input type="text" id="username"/>
<input type="button" id="btn" value="jquery形式的get异步请求" onclick="fun()">
<div id="myDiv"></div>
</body>
<script type="text/javascript">
function fun() {
// url : 提交的服务器路径
// data: 提交的数据
// params 参数列表
// callback:回调函数,响应成功之后再去执行的函数。
// type: 期望响应回来的数据类型。
// text 默认形式 文本形式。
// json形式。
var url = "http://127.0.0.1:8080/ajaxStudy"
var params = "name=" + $("#username").val()
// $.post
$.get(url, params,
// 回调函数,如果响应成功就执行该函数,data代表服务器的响应数据
function(data) {
$("#myDiv").html(data);
}, "text")
}
</script>
</html>
$.ajax()
$.get() $.post()
的底层是$.ajax()
上层函数是对底层函数的封装,有较多的默认值。
$.get() $.post()
简单易用,但是如果需要操作不常用的参数时,需要使用$.ajax()
// settings 配置集
// async : true异步 false同步 默认是异步
//
// data : 请求参数 params
//
// dataType: 等同于type 期望响应回来的数据类型 默认text json
//
// success:成功之后的回调函数 function(data){}
//
// error : 失败之后的回调函数 function(){}
//
// type: 提交方式 get |post 默认是get提交
$.ajax(url,[settings])
使用方式
$.ajax({
url:请求路径,
data:请求参数
...
...
})
package com.lx.servlet.ajaxTest;
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;
@WebServlet("/jqueryAjaxGet")
public class AjaxTest extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name");
System.out.println(name);
System.out.println(1/0);
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().write(name);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jquery形式的异步请求之get请求</title>
<!--引入jquery文件-->
<script src="../js/jquery-1.11.0.min.js" type="text/javascript"></script>
</head>
<body>
<input type="button" id="btn" value="jquery形式的get异步请求" onclick="fun()">
<div id="myDiv"></div>
</body>
<script type="text/javascript">
// 使用底层函数 来进行ajax异步请求操作
function fun() {
var url = "/jqueryAjaxGet"
var params = "name=丽丽"
$.ajax({
url: url,
data: params,
type: "get",
dataType: "text",
success: function (data) {
$("#myDiv").html(data);
},
error: function () {
alert("error")
}
})
}
</script>
</html>
$.ajax()实例
$.ajax({
url:"http://www.microsoft.com", //请求的url地址
dataType:"json", //返回格式为json(期望服务器响应回来的数据形式)
// 还有text和xml,html
// html----浏览器会对返回的内容进行页面渲染,在freeMarker中,就是返回后端返回的那个页面
// text----纯文本,浏览器不会对返回的内容进行渲染,将html的内容文本原封不动的显示在浏览器上
async:true,//请求是否异步,默认为异步,这也是ajax重要特性
data:{"id":"value"}, //参数值,是一个json
type:"GET", //请求方式
contentType: "application/json;charset=utf-8",
// 解决跨域问题
xhrFields: {withCredentials: true},
beforeSend:function(){
//请求前的处理
},
success:function(data){
//回调函数 ,成功时返回的数据存在形参data里
//请求成功时处理
},
complete:function(){
//请求完成的处理
},
error:function(){
//请求出错处理
}
})
json
数据交互格式,同类的还有xml
// 对象
{"name":"lisi","age":12}
// 数组
[]
[{"name":"lisi","age":12},{"name":"lisi","age":12}]
{"fruit":["apple","banana","mango"]}
com.alibaba.fastjson.JSON
package com.example.javasestudy.json;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class FastJsonTest {
public static void main(String[] args) {
System.out.println("=====================对象==================================");
System.out.println("=====================java对象 json字符串 互转===================");
Student student = new Student("bob", 24);
String str1 = JSON.toJSONString(student);
// {"age":24,"name":"bob"}
System.out.println(str1);
Student stu1 = JSON.parseObject(str1, Student.class);
// Student(name=bob, age=24)
System.out.println(stu1);
System.out.println("=====================java对象 json对象 互转===================");
JSONObject jsonObject1 = (JSONObject) JSON.toJSON(student);
System.out.println(jsonObject1.getString("name"));
Student student2 = JSON.toJavaObject(jsonObject1, Student.class);
// Student(name=bob, age=24)
System.out.println(student2);
System.out.println("=====================java集合 json集合 互转===================");
List<Student> students = Arrays.asList(new Student("zs", 3), new Student("ls", 4));
JSONArray jsonArrays = (JSONArray) JSON.toJSON(students);
Object o = jsonArrays.get(0);
System.out.println(o);
List<Student> students1 = jsonArrays.toJavaList(Student.class);
System.out.println(students1);
// json字符串集合 转 json集合
JSONArray jArray = JSON.parseArray(JSON.toJSONString(students));
System.out.println(jArray);
System.out.println("===============日期转换 localdatetime 和转换java对象的使用方式一样=======================");
}
}
com.fasterxml.jackson
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>javase-study</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>javase-study</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
package com.example.javasestudy.json;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String name;
private Integer age;
private String city;
public User(String name, Integer age, String city) {
this.name = name;
this.age = age;
this.city = city;
}
private LocalDateTime localDateTime;
}
package com.example.javasestudy.json;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.lang.reflect.Type;
import java.time.LocalDateTime;
import java.util.*;
@SpringBootTest
public class JacksonTest {
// registerModule(new JavaTimeModule()) jackson默认不能对localDatetime解析,加上这个就可以了
private static ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule());
@Test
public void test1() throws JsonProcessingException {
System.out.println("============java对象 json字符串 互转===============");
//对象转json
User user = new User("tom",23,"上海");
String json = objectMapper.writeValueAsString(user);
System.out.println(json);
//json转对象
User uuser = objectMapper.readValue(json, User.class);
System.out.println(uuser);
// {"name":"tom","age":23,"city":"上海"}
// User(name=tom, age=23, city=上海)
System.out.println("============java对象 json对象 互转===============");
User user3 = new User("tom",23,"上海");
JsonNode jsonNode = objectMapper.valueToTree(user3);
System.out.println(jsonNode);
System.out.println(jsonNode.get("name"));
User user4 = objectMapper.treeToValue(jsonNode, User.class);
System.out.println(user4);
System.out.println("===================java集合 json字符串 互转===========================");
// 如果泛型的参数是基本类型的包装类,那么和 对象 json 互转的方式一样
//list<User>转json
List<User> ulist = new ArrayList<>();
ulist.add(user);
String ujson = objectMapper.writeValueAsString(ulist);
System.out.println(ujson);
//json转list<User>
JavaType jt = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, User.class);
List<User> urlist = objectMapper.readValue(ujson, jt);
System.out.println(urlist);
System.out.println("===================java集合 json集合 互转===========================");
// 好像没有,是 objectMapper.createArrayNode() 创建一个json集合然后放进去,没有直接转的
System.out.println("===================map===========================");
// 如果泛型的参数是基本类型的包装类,那么和 对象 json 互转的方式一样
//map<String,User>转json
HashMap<String, User> umap = new HashMap<String, User>();
umap.put(user.getName(), user);
String mmjson = objectMapper.writeValueAsString(umap);
System.out.println(mmjson);
//json转map<String,User>
// JavaType jvt = objectMapper.getTypeFactory().constructParametricType(HashMap.class,String.class,User.class);
// 也可以这样
Map<String,User> urMap = objectMapper.readValue(mmjson, new TypeReference<Map<String, User>>() {});
System.out.println(urMap);
System.out.println("===============忽略不存在的属性=======================");
// 如果在进行 JSON 转 Java 对象时,JSON 中出现了 Java 类中不存在的属性,
// 那么在转换时会遇到 com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException 异常。
String json2 = "{\"yyy\":\"xxx\",\"name\":\"LaoWang\",\"age\":28,\"skillList\":[\"java\",\"c++\"]}";
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
User user1 = objectMapper.readValue(json2, User.class);
// User(name=LaoWang, age=28, city=null)
System.out.printf(user1.toString());
System.out.println("====================日期转换=====================");
User user2 = new User("kk", 30, "北京", LocalDateTime.of(2024, 04, 22, 11, 16));
String s = objectMapper.writeValueAsString(user2);
// {"name":"kk","age":30,"city":"北京","localDateTime":[2024,4,22,11,16]}
System.out.println(s);
// User(name=kk, age=30, city=北京, localDateTime=2024-04-22T11:16)
System.out.println(objectMapper.readValue(s, User.class));
}
}
暂时只看fastjson和jackson,下面这两个用到再说
net.sf.json.JSONObject
对象的方法
// 将json串转换成java对象
JSONObject JSONObject.fromObject(String s)
// 对象通过key获取相应的值
String getString(String s)
// 将java对象换成json串
JSONObject JSONObject.fromObject(String s).toString
// 这个方法转换的json串值如果为null的话,转换过来不是null是字符串null
// 这个方法如果对象的属性是Date类型的话,它不会直接输出字符串,而是某个月的某个星期,某个星期的某天类似这样的;
// 而且这个方法会把你这个类中所有的属性都输出,而fastjson只会输出你赋值的属性。
// 关于输出日期的这个毛病,jackson同样存在。
数组的方法
//将json串转换成java集合
JSONArray JSONArray.fromObject(String s)
//获取索引对应的对象
JSONObject getJSONObject(int index)
总结几点坑
- 当json数据的value为null时,转换成对象,获取该对象的value,使用==与null(null是代表空,不是字符串)比较,结果为false;
- 在Java对象转换JSON对象时,get开头的所有方法会被转换。
- 它把对象转换成json串的方式,把所有的属性包括为null的全部输出;尤其是日期,你输入一个yyyy-MM-dd类型日期,它会输出,日历类型,一年中的哪个月,一个月的哪天等等,总之不是我想要的。
Gson
输出的json数据要求跟原始javabean不一样以及日期的格式化
简单的javabean对象
package com.zhdw.mgrclient.test;
import java.util.Date;
public class Person {
private String name;
private int age;
private Date birthday;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
测试类
package com.zhdw.mgrclient.test;
import java.util.Date;
import com.google.gson.Gson;
public class JSONTest {
public static void main(String[] args) {
Person hbk = new Person();
hbk.setAge(30);
hbk.setName("黄宝康");
hbk.setBirthday(new Date());
Gson gson = new Gson();
String result = gson.toJson(hbk);
System.out.println(result);
}
}
输出结果
{"name":"黄宝康","age":30,"birthday":"May 21, 2018 11:50:23 AM"}
需求,我需要输出NAME,而不是小写的name,
第二,日期格式不是我想要的。
Gson针对这两个问题,提供了相关注解,只需要在Person的name字段加入相关注解即可。
@SerializedName("NAME")
private String name;
再次运行输出如下:可以看出name已经输出成NAME了,第一个问题解决。
{"NAME":"黄宝康","age":30,"birthday":"May 21, 2018 11:53:25 AM"}
使用GsonBuilder()构建Gson对象,而不是之前的new Gson();
这样运行输出了我们想要的格式。
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
{"NAME":"黄宝康","age":30,"birthday":"2018-05-21 11:57:16"}
部分内容引用自:
https://blog.csdn.net/huangbaokang/article/details/80390349
想了这几天,我想出唯一的解决之道了,我不能只喜欢老师,我要爱上他。
你爱的人要对你做什么都可以,不是吗?
思想是一种多么伟大的东西!
我是从前的我的赝品。
我要爱老师,否则我太痛苦了。
房思琪的初恋乐园
林奕含