跳到主要内容JavaWeb 核心:JSON 数据交换与 Ajax 异步请求详解 | 极客日志Java大前端java
JavaWeb 核心:JSON 数据交换与 Ajax 异步请求详解
本文详细讲解了 Web 开发中的数据交换与异步请求技术。首先介绍了 JSON 格式的定义、规则及其在 JavaScript 和 Java(Gson 库)中的对象与字符串转换实战,重点说明了 TypeToken 在泛型转换中的应用。接着阐述了 Ajax 技术的原理,对比了原生 XMLHttpRequest 与 jQuery 封装方法的优劣及代码实现。最后深入分析了 ThreadLocal 在线程数据隔离中的作用机制及源码逻辑,帮助开发者构建高效安全的 Web 应用。
JavaWeb 核心:JSON 数据交换与 Ajax 异步请求详解
一、数据交换——JSON
1. JSON 简介
JSON(JavaScript Object Notation)是一种轻量级的文本数据交换格式。它独立于编程语言,无论是 Java、PHP、Go 还是其他语言都能轻松解析。JSON 具有自我描述性,结构清晰,非常适合前后端交互。

2. JSON 快速入门
定义格式
var myJson = {
"k1": value,
"k2": "value",
"k3": [],
"k4": {},
"k5": [{}, {}]
};
规则解读
- 键值对:映射用冒号
: 表示,"名称": 值。注意键名必须是双引号包裹的字符串。
- 分隔符:并列的数据项之间用逗号
, 分隔。
- 集合:对象用大括号
{} 包裹,数组用方括号 [] 包裹。
- 数据类型:支持
string, number, object, array, true, false, null。
案例演示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<>json 快速入门案例
json 快速入门案例
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].k2= " + myJson.key5[0].k2);
</script>
</head>
<body>
<h1>
</h1>
</body>
</html>
3. JSON 对象与字符串转换
在实际开发中,我们常需要在 JSON 对象和字符串之间转换。
JSON.stringify(json): 将 JSON 对象转换为 JSON 字符串(序列化)。
JSON.parse(jsonString): 将 JSON 字符串转换为 JSON 对象(反序列化)。
var jsonObj = {
"name": "韩顺平教育",
age: 10
};
var jsonStr = JSON.stringify(jsonObj);
console.log(jsonStr);
var jsonObj2 = JSON.parse(jsonStr);
console.log(jsonObj2);
JSON.stringify() 返回字符串,不影响原对象。
JSON.parse() 返回对象,不影响原字符串。
- 定义 JSON 对象时,键名建议使用双引号;但在原生字符串转 JSON 对象时,必须使用双引号,否则可能报错。
4. JSON 在 Java 中使用
Java 处理 JSON 通常引入第三方库,这里以 Google 的 Gson 为例。
应用场景
- JavaBean 对象与 JSON 字符串互转
- List 集合与 JSON 字符串互转
- Map 集合与 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);
底层通过反射机制实现,Book.class 指定了目标类型。
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);
对象或集合转字符串相对简单,Gson 内部遍历拼接即可。
3. JSON 字符串转 List 对象
复杂类型转换需要使用 TypeToken 来指定泛型信息。
Type type = new TypeToken<List<Book>>(){}.getType();
List<Book> bookList2 = gson.fromJson(strBookList, type);
System.out.println("bookList2=" + bookList2);
为什么加 {}?
TypeToken 的构造器是 protected 的,不能直接实例化。使用匿名内部类 new TypeToken<>(){} 可以创建子类,利用隐式无参构造器调用父类构造器,从而获取完整的泛型类型路径。
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);
Map<String, Book> bookMap2 = gson.fromJson(
strBookMap,
new TypeToken<Map<String, Book>>(){}.getType()
);
二、异步请求——Ajax
1. 基本介绍
AJAX(Asynchronous Javascript And XML)是一种允许网页无需刷新即可与服务器交换数据的技术。
- 搜索引擎关键字自动提示
- 动态加载数据(树形菜单、联动菜单)
- 表单验证(如用户名是否被占用)
- 局部页面刷新
2. JavaScript 原生 Ajax 请求
原生 Ajax 基于 XMLHttpRequest 对象。
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;
}
};
xhr.send();
};
};
问题分析: 原生写法代码量大,且需处理浏览器兼容性问题。实际工作中更倾向于使用封装好的库。
3. JQuery 的 Ajax 请求
JQuery 简化了 Ajax 操作,提供了 $.ajax, $.get, $.post, $.getJSON 等方法。
url: 请求地址
type: 请求方式 (get/post)
data: 发送的数据
success: 成功回调函数
error: 失败回调函数
dataType: 预期返回数据类型 (json/text/xml)
$.ajax({
url: '/ajax/checkUserServlet',
type: 'GET',
data: {uname: 'test'},
dataType: 'json',
success: function(data) {
console.log('验证结果:', data);
},
error: function(xhr) {
console.error('请求失败');
}
});
三、线程数据共享和安全 - ThreadLocal
1. ThreadLocal 基本介绍
在多线程环境下,ThreadLocal 用于解决线程间的数据隔离问题,确保每个线程拥有独立的变量副本。
- 为当前线程关联一个数据(普通变量、对象等)。
- 类似 Map 存取,Key 是当前线程,Value 是存储的数据。
- 每个 ThreadLocal 实例只能为一个线程关联一个数据。
- 线程销毁后,数据自动释放。
ThreadLocal<Object> threadLocal = new ThreadLocal<>();
threadLocal.set(dog);
若需存储多个对象,需创建多个 ThreadLocal 实例。
2. 源码分析
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 的内部类,与线程绑定。
- Entry 的 Key 是
ThreadLocal 对象本身,Value 是存储的值。
- 内存布局上,每个线程都有自己的
ThreadLocalMap,实现了数据隔离。
关于弱引用等细节较为深入,此处暂不展开,但理解上述机制已足够应对大多数并发场景。
相关免费在线工具
- 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