跳到主要内容JavaWeb 数据交换与异步请求:JSON 与 Ajax 技术解析 | 极客日志Java大前端java
JavaWeb 数据交换与异步请求:JSON 与 Ajax 技术解析
介绍 JavaWeb 中的数据交换与异步请求技术。首先讲解 JSON 格式、快速入门及对象字符串转换,演示 Java 中使用 Gson 库进行对象映射。其次阐述 Ajax 原理,对比原生 JavaScript 与 JQuery 的 Ajax 请求实现方式。最后简要说明 ThreadLocal 在线程数据共享与安全中的应用。旨在帮助开发者掌握前后端数据交互核心技能。
清酒独酌29 浏览 JavaWeb 数据交换与异步请求:JSON 与 Ajax 技术解析

一、数据交换–JSON
1. JSON 介绍
- JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation)
- JSON 是轻量级的文本数据交换格式
- JSON 独立于语言(即 java、php、asp.net、go 等都可以使用 JSON)
- JSON 具有自我描述性,更易理解,非常实用。

2. JSON 快速入门
1. JSON 的定义格式
var 变量名 = {
"k1": value,
"k2": "value",
"k3": [],
"k4": {},
"k5": [{},{}]
};
2. 解读 JSON 规则
- 映射 (元素/属性) 用冒号
: 表示,"名称":值,注意名称是字符串,因此要用双引号引起来。
- 并列的数据之间用逗号
, 分隔。"名称 1":值,"名称 2":值
- 映射的集合 (对象) 用大括号
{} 表示。{"名称 1":值,"名称 2":值}
- 并列数据的集合(数组)用方括号
[] 表示。[{"名称 1":值,"名称 2":值}, {"名称 1":"名称 2":值}]
- 元素值类型:
string, number, object, array, true, false, null
3. JSON 快速入门案例
<!DOCTYPE >
json 快速入门案例
json 快速入门案例
html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>
</title>
<script type="text/javascript">
var myJson = {
"key1": "教育",
"key2": 123,
"key3": [1, "hello", 2.3],
"key4": {"age":12,"name":"jack"},
"key5": [
{"k1":10,"k2":"milan"},
{"k3":30,"k4":"smith"}
]
};
console.log("key1= "+ myJson.key1);
console.log("key3[1]= "+ myJson.key3[1]);
console.log("name= "+ myJson.key4.name);
console.log("myJson.key5[0]= "+ myJson.key5[0]);
console.log("myJson.key5[0].k2= "+ myJson.key5[0].k2);
</script>
</head>
<body>
<h1>
</h1>
</body>
</html>
3. JSON 对象和字符串对象转换
1. 应用案例
JSON.stringify(json) 功能:将一个 json 对象转换成为 json 字符串。
JSON.parse(jsonString) 功能:将一个 json 字符串转换成为 json 对象。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JSON 对象和字符串对象转换</title>
<script type="text/javascript">
var jsonObj = {
"name": "韩顺平教育",
age: 10
};
console.log(JSON);
var jsonStr = JSON.stringify(jsonObj);
console.log(jsonStr);
var jsonObj2 = JSON.parse(jsonStr);
console.log(jsonObj2);
</script>
</head>
<body>
<h1>JSON 对象和字符串对象转换</h1>
</body>
</html>
2. 注意事项和细节
JSON.stringify(jsonObject) 会返回对应 string,并不会影响原来 json 对象。
JSON.parse(string) 函数会返回对应的 json 对象,并不会影响原来 string。
- 在定义 Json 对象时,可以使用
' ' 表示字符串。
例如 var json_person = {"name": "jack", "age": 100};
也可以写成 var json_person = {'name': 'jack', 'age': 100};
- 但是在把原生字符串转成 json 对象时,必须使用
"",否则会报错。
例如:var str_dog = "{'name':'小黄狗', 'age': 4}"; 转 json 就会报错。
JSON.stringify(jsonObject) 返回的字符串,都是 "" 表示的字符串,所以在语法格式正确的情况下,是可以重新转成 json 对象的。
4. JSON 在 Java 中使用
1. 说明
- Java 中使用 json,需要引入第三方的包
gson.jar。
- Gson 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的 Java 类库。
- 可以对 JSON 字符串 和 Java 对象相互转换。
2. JSON 在 Java 中应用场景
- JavaBean 对象和 json 字符串 的转换
- List 对象和 json 字符串 的转换
- Map 对象和 json 字符串 的转换
3. 应用场景示意图
5. 代码演示
1. 代码演示:演示 JavaBean 和 JSON 字符串的转换
Gson gson = new Gson();
Book book = new Book(100, "零基础学 Java");
String strBook = gson.toJson(book);
System.out.println("strBook=" + strBook);
Book book2 = gson.fromJson(strBook, Book.class);
System.out.println("book2=" + book2);
解读
(1) strBook 就是 json 字符串
(2) Book.class 指定将 json 字符串转成 Book 对象
(3) 底层是反射机制
2. 代码演示:演示把 List 对象 -> JSON 字符串
List<Book> bookList = new ArrayList<>();
bookList.add(new Book(200, "天龙八部"));
bookList.add(new Book(300, "三国演义"));
String strBookList = gson.toJson(bookList);
System.out.println("strBookList= " + strBookList);
因为把对象,集合转成字符串,相对比较简单,底层只需要遍历,按照 json 格式拼接返回即可。
3. 代码演示:演示把 JSON 字符串 -> List 对象
(1) 如果需要把 json 字符串 转成 集合这样复杂的类型,需要使用 gson 提供的一个类。
(2) TypeToken,是一个自定义泛型类,然后通过 TypeToken 来指定我们需要转换成的类型。
Type type = new TypeToken<List<Book>>(){}.getType();
List<Book> bookList2 = gson.fromJson(strBookList, type);
System.out.println("bookList2= " + bookList2);
(1) 返回类型的完整路径 java.util.List<com.hspedu.json.Book>
(2) gson 的设计者,需要得到类型的完整路径,然后进行底层反射
(3) 所以 gson 设计者就提供 TypeToken,来搞定。
== 使用 TypeToken,为什么要加 {} ==
首先我们看一下 TypeToken 的源码。
package com.google.gson.reflect;
public class TypeToken<T> {
final Class<? super T> rawType;
final Type type;
final int hashCode;
protected TypeToken() {
this.type = getSuperclassTypeParameter(this.getClass());
this.rawType = Types.getRawType(this.type);
this.hashCode = this.type.hashCode();
}
}
(1) 如果我们 new TypeToken<List<Book>>()
错误提示 'TypeToken()' has protected access in 'com.google.gson.reflect.TypeToken'
(2) 因为 TypeToken 的无参构造器是 protected,而 new TypeToken<List<Book>>() 就是调用其无参构造器
(3) 根据 java 基础,如果一个方法是 protected,而且不在同一个包,是不能直接访问的,因此报错
(4) 为什么 new TypeToken<List<Book>>(){} 使用就可以,这里就涉及到匿名内部类的知识。
(5) 当 new TypeToken<List<Book>>(){} 其实这个类型就不是 TypeToken 而是一个匿名内部类 (子类),继承
(6) 而且这个匿名内部类是有自己的无参构造器 (隐式),根据 java 基础规则,当执行子类的无参构造器时,默认 super();
4. 代码演示:演示把 Map 对象 -> JSON 字符串 (与 List 基本一致)
Map<String, Book> bookMap = new HashMap<>();
bookMap.put("k1", new Book(400, "射雕英雄传"));
bookMap.put("k2", new Book(500, "西游记"));
String strBookMap = gson.toJson(bookMap);
System.out.println("strBookMap=" + strBookMap);
Map<String, Book> bookMap2 = gson.fromJson(strBookMap, new TypeToken<Map<String, Book>>(){}.getType());
二、异步请求–Ajax
1. 基本介绍
1. Ajax 是什么
- AJAX 即 "Asynchronous Javascript And XML" (异步 JavaScript 和 XML)
- Ajax 是一种浏览器异步发起请求 (指定发哪些数据),局部更新页面的技术
- 搜索引擎根据用户输入关键字,自动提示检索关键字
- 动态加载数据,按需取得数据【树形菜单、联动菜单…】
- 改善用户体验。【输入内容前提示、带进度条文件上传…】
- 电子商务应用。【购物车、邮件订阅…】
- 访问第三方服务。【访问搜索服务、rss 阅读器】
- 页面局部刷新
2. Ajax 原理示意图
2. JavaScript 原生 Ajax 请求
1. Ajax 文档
2. 通过问题引出 Ajax
点击验证用户名,使用 ajax 方式,服务端验证该用户名是否已经占用了,如果该用户已经占用,以 json 格式返回该用户信息。
<script type="text/javascript">
window.onload = function(){
var checkButton = document.getElementById("checkButton");
checkButton.onclick = function(){
var xhr = new XMLHttpRequest();
var uname = document.getElementById("uname").value;
xhr.open("GET","/ajax/checkUserServlet?uname=" + uname,true);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
document.getElementById("div1").innerHTML = xhr.responseText;
var responseText = xhr.responseText;
xhr.send();
}
}
}
}
</script>
3. 原生 Ajax 请求问题分析
- 编写原生的 Ajax 要写很多的代码,还要考虑浏览器兼容问题,使用不方便。
- 在实际工作中,一般使用 JavaScript 的库 (比如 Jquery) 发送 Ajax 请求,从而解决这个问题。
3. JQuery 的 Ajax 请求
1. JQuery Ajax 操作方法
2. $.ajax 方法
$.ajax 常用参数
url: 请求的地址
type: 请求的方式 get 或 post
data: 发送到服务器的数据。将自动转换为请求字符串格式
success: 成功的回调函数
error: 失败后的回调函数
dataType: 返回的数据类型 常用 json 或 text
- 说明:完整的参数参看手册。
3. $.get 请求和 $.post 请求
$.get 和 $.post 常用参数
url: 请求的 URL 地址
data: 请求发送到服务器的数据
success: 成功时回调函数
type: 返回内容格式,xml, html, script, json, text
- 说明:
$.get 和 $.post 底层还是使用 $.ajax() 方法来实现异步请求。
4. $.getJSON
$.getJSON 常用参数
url: 请求发送的哪个 URL
data: 请求发送到服务器的数据
success: 请求成功时运行的函数
- 说明:
$.getJSON 底层使用 $.ajax() 方法来实现异步请求。
三、线程数据共享和安全 - ThreadLocal
1. ThreadLocal 基本介绍
1. 什么是 ThreadLocal
- ThreadLocal 的作用,可以实现在同一个线程数据共享,从而解决多线程数据安全问题。
- ThreadLocal 可以给当前线程关联一个数据 (普通变量、对象、数组) set 方法。
- ThreadLocal 可以像 Map 一样存取数据,key 为当前线程,get 方法。
- 每一个 ThreadLocal 对象,只能为当前线程关联一个数据,如果要为当前线程关联多个数据,就需要使用多个 ThreadLocal 对象实例。
- 每个 ThreadLocal 对象实例定义的时候,一般为 static 类型。
- ThreadLocal 中保存数据,在线程销毁后,会自动释放。
ThreadLocal<Object> threadLocal = new ThreadLocal<>();
threadLocal.set(dog);
如果希望在同一个线程共享多个对象/数据,就在创建一个 ThreadLocal 对象
//threadLocal2.set(pig);
2. 源码分析
1. set 源码分析
只要明白这个机制,后面的 set get 全部通透。
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if(map != null) map.set(this, value);
else createMap(t, value);
}
说明:
- ThreadLocalMap 对象是和当前 Thread 对象的绑定的属性
- ThreadLocalMap 对象含有 Entry[] table; 这个 Entry(K,V)
- 这个 key 就是 ThreadLocal 对象,V 就是你要放入的对象,比如 dog
- 当执行了 threadLocal.set(dog) 后,内存布局图为 [看图]
2. Debug 源码图
相关免费在线工具
- Keycode 信息
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
- Escape 与 Native 编解码
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
- JavaScript / HTML 格式化
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
- JavaScript 压缩与混淆
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online