跳到主要内容JavaWeb 核心:JSON 数据交换与 Ajax 异步请求实战 | 极客日志Java大前端java
JavaWeb 核心:JSON 数据交换与 Ajax 异步请求实战
本文详解 Web 开发中的数据交换与异步请求技术。涵盖 JSON 格式规范及 Java 中 Gson 库的序列化用法,包括对象、集合与 Map 的转换细节;解析原生 Ajax 与 jQuery 封装的差异及实现流程;最后剖析 ThreadLocal 在线程隔离中的应用原理与源码机制,助力构建高效安全的 Web 应用。
数字游民1 浏览 
在 Web 开发中,数据交换和异步请求是构建现代交互体验的基石。JSON 作为轻量级的数据格式,配合 Ajax 技术实现局部刷新,已成为前后端分离架构中的标配。本文将深入探讨 JSON 的语法规范、Java 中的集成应用,以及 Ajax 的实现原理与优化方案。
一、数据交换 – JSON
1. JSON 介绍
JSON(JavaScript Object Notation)是一种轻量级的文本数据交换格式。它独立于编程语言,无论是 Java、PHP、Go 还是其他语言都能轻松解析。其自我描述性强,结构清晰,非常适合用于 API 数据传输。
2. JSON 快速入门
JSON 遵循特定的语法规则,理解这些规则是编写正确数据的基础。
基本定义:
var myJson = {
"k1": 123,
"k2": "value",
"k3": [],
"k4": {},
"k5": [{}, {}]
};
核心规则:
- 键值对:使用冒号
: 分隔,键名必须是双引号包裹的字符串。
- 分隔符:并列元素之间用逗号
, 分隔。
- 集合:对象用大括号
{} 表示,数组用方括号 [] 表示。
- 数据类型:支持
string, number, object, array, true, false, null。
示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta =>
json 快速入门案例
json 快速入门案例
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].k2= " + myJson.key5[0].k2);
</script>
</head>
<body>
<h1>
</h1>
</body>
</html>
3. JSON 对象与字符串转换
在实际开发中,经常需要在内存中的对象和网络传输的字符串之间进行转换。
JSON.stringify(json): 将 JSON 对象序列化为字符串。
JSON.parse(jsonString): 将 JSON 字符串反序列化为对象。
- 转换操作不会修改原始对象或字符串。
- 原生 JS 定义对象时单双引号混用可能没问题,但
JSON.parse() 接收的字符串必须严格使用双引号,否则会报错。
var jsonObj = {
"name": "韩顺平教育",
"age": 10
};
var jsonStr = JSON.stringify(jsonObj);
console.log(jsonStr);
var jsonObj2 = JSON.parse(jsonStr);
console.log(jsonObj2);
4. JSON 在 Java 中使用
Java 本身没有内置的 JSON 处理类库,通常引入第三方包如 gson.jar。Gson 是 Google 提供的工具,能高效地在 Java 对象和 JSON 数据之间映射。
- 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);
3. 复杂泛型转换 (TypeToken)
当需要将 JSON 字符串转换为泛型集合时,由于 Java 的类型擦除特性,需要借助 TypeToken 来获取完整的类型信息。
Type type = new TypeToken<List<Book>>(){}.getType();
List<Book> bookList2 = gson.fromJson(strBookList, type);
System.out.println("bookList2= " + bookList2);
为什么加 {}?
TypeToken 的构造函数是 protected 的,不能直接实例化。使用匿名内部类 new TypeToken<>(){} 可以创建子类并访问 protected 构造器,同时保留泛型信息供底层反射使用。
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 请求
虽然现代框架层出不穷,但理解原生的 XMLHttpRequest 依然重要。
- 创建
XMLHttpRequest 对象。
- 配置请求(
open),设置 URL、方法(GET/POST)、是否异步。
- 监听状态变化(
onreadystatechange)。
- 发送请求(
send)。
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 调用,提供了更简洁的 API。
$.ajax(): 通用方法,可配置所有参数。
$.get() / $.post(): 快捷方式,分别对应 GET 和 POST。
$.getJSON(): 专门用于处理 JSON 响应。
url: 请求地址。
type: 请求方式(get/post)。
data: 发送的数据。
success: 成功回调函数。
dataType: 预期返回的数据类型(json/text/xml)。
三、线程数据共享和安全 - ThreadLocal
在 Web 多线程环境下,ThreadLocal 提供了一种线程隔离的解决方案,确保每个线程拥有独立的变量副本。
1. 基本介绍
ThreadLocal 的作用是为当前线程提供一个私有存储空间。它像一个 Map,Key 是当前线程,Value 是存储的对象。每个 ThreadLocal 实例只能关联一个数据,若需多个数据则需创建多个实例。通常定义为 static 类型,线程销毁后数据自动释放。
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 是存储的值。
- 执行
threadLocal.set(dog) 后,数据实际上存储在所属线程的 ThreadLocalMap 中,而非 ThreadLocal 对象本身。
这种设计保证了不同线程之间的数据互不干扰,有效解决了并发环境下的数据安全问题。
相关免费在线工具
- 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