第一章:JSON 通述——简易数据交换格式

1.1 什么是 JSON?

JSON (JavaScript Object Notation) 是一种基于文本的、独立于语言的轻量级数据交换格式。

  • 历史渊源:由 Douglas Crockford 在 2001 年“发现”并推广。为什么要说“发现”?因为他在 JS 既有的语法中看到了一种完美的结构化数据表达方式。

  • 诞生背景:在 2000 年代初期,大家都在痛苦地使用 XML 进行前后端通信。XML 太重了,解析起来像是在剥洋葱。JSON 的出现就像是从繁重的电报进化到了即时短信。

1.2 核心价值

  • 轻量级:没有冗余的标签。

  • 自描述性:即便没有文档,开发者扫一眼键值对(Key-Value)也能猜出数据含义。

  • 语言无关:虽然名字里带 JavaScript,但它现在是所有主流编程语言的标配。

1.3 王者之争:JSON vs. XML

这是 Blog 的核心看点之一,建议用表格呈现:

维度 JSON XML
可读性 简洁,接近原生代码对象 复杂,被大量标签包裹
解析效率 极快(JS 引擎原生支持) 慢(需要 DOM/SAX 解析器)
数据体积 小(平均比 XML 小 30% 以上)
数组支持 原生支持 [ ] 需通过重复标签模拟
注释支持 不支持 支持

1.4 为什么 YAML 和 TOML 没能取代 JSON?

  • JSON:设计初衷是数据传输。它语法极其严苛,不容易在传输中产生歧义。

  • YAML / TOML:设计初衷是人类编写配置文件。YAML 的缩进和 TOML 的分区对人类友好,但解析器的复杂度和歧义性使其不适合大规模、高频率的 API 传输。


第二章:语法精通 —— 每一个字符都马虎不得

2.1 六大基础数据类型详解

1. String(字符串)

必须用双引号包裹。支持转义字符。

  • 实例"greeting": "Hello, \"World\" \nWelcome to 2026!"

  • 注意:可以包含 Unicode 字符(如 \u4f60\u597d 表示“你好”)。

2. Number(数值)

支持整数、浮点数和科学计数法。

  • 实例

    • 整数:"age": 25

    • 浮点数:"price": 99.99

    • 科学计数法:"mass": 5.972e24 (地球质量)

  • 注意:不支持 NaNInfinity

3. Boolean(布尔值)

必须全小写。

  • 实例"is_admin": true, "is_deleted": false

  • 注意"True" (字符串) $\neq$ true (布尔)。

4. Null(空值)

表示一个空引用。

  • 实例"middle_name": null

5. Object(对象)

大括号包裹的键值对。

  • 实例

    {
      "user": {
        "id": 1,
        "name": "Gemini"
      }
    }
    
6. Array(数组)

中括号包裹的有序集合。

  • 实例"tags": ["AI", "Tech", 2026](JSON 数组允许包含不同类型的元素,但在实践中不推荐)。

2.2 JSON 的严格模式(五大红线)

作为博主,这里你要重点强调,这是初学者最容易报错的地方:

  1. 双引号原则:所有键(Key)和字符串值(Value)必须用双引号。单引号 ' ' 在标准 JSON 中是非法的。

  2. 末尾逗号禁忌:最后一个键值对后面千万不能加逗号。

    • {"a": 1, "b": 2,}

    • {"a": 1, "b": 2}

  3. 禁止注释:JSON 文件中严禁出现 ///* */

  4. 键名必须是字符串:在 JS 中你可以写 { name: "A" },但在 JSON 中必须是 { "name": "A" }

  5. 编码:强制使用 UTF-8


第三章:程序设计中的 JSON 处理(纠错与进阶)

3.1 Java 篇 (以 Jackson 库为例)

在 Java 生态中,Jackson 是处理 JSON 的行业标准。

  • 对象转字符串 (Serialization)

     
    ObjectMapper mapper = new ObjectMapper();
    User user = new User("Alice", 20);
    String jsonString = mapper.writeValueAsString(user); 
    
  • 字符串转对象 (Deserialization)

     
    User user = mapper.readValue(jsonString, User.class);
    

3.2 Kotlin 篇 (使用 Kotlinx.serialization)

Kotlin 官方推荐的方式,具有类型安全和高性能的特点。

@Serializable
data class User(val name: String, val age: Int)

// 序列化
val jsonData = Json.encodeToString(User("Bob", 22))

// 反序列化
val user = Json.decodeFromString<User>(jsonData)

3.3 跨语言的共同挑战

  • 日期处理:JSON 没日期类型,推荐使用 ISO 8601 字符串:"2026-03-24T14:30:00Z"

  • 大数丢失精度

    • 案例:数据库的 ID 是 9007199254740993

    • 问题:JS 解析时会变成 9007199254740992(精度丢失)。

    • 对策:后端在生成 JSON 时,务必将此类 ID 转为 String 类型。


第四章:JSON Schema —— 数据质检员

这是让你的 Blog 显得“高级”的部分。

实战:用户信息校验器

假设我们要校验一份注册数据,要求:

  1. 必须有 username 且长度 $\ge 3$。

  2. age 必须是 18-100 之间的整数。

Schema 定义:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "username": { "type": "string", "minLength": 3 },
    "age": { "type": "integer", "minimum": 18, "maximum": 100 }
  },
  "required": ["username", "age"]
}

第五章:高级工程实践与性能优化

5.1 复杂 JSON 结构设计技巧

在设计 API 时,结构的优劣直接影响前端的渲染效率。

  • 扁平化 (Flattening) vs. 深层嵌套

    • 深层嵌套:结构清晰,符合逻辑,但前端取值很痛苦(如 data.user.profile.address.city)。

    • 扁平化:减少解析层级,提高查询效率,适合高性能要求的场景。

  • 数据冗余与引用的平衡

    • 如果在 JSON 中多处引用同一个用户信息,是重复发送该对象(冗余),还是只发送 user_id(引用)?

    • 建议:频繁变动的数据用“引用”,追求一次性渲染展示的数据用“冗余”。

5.2 大数据量下的 JSON 处理

当 JSON 文件达到几百 MB 甚至 GB 级别时,传统的 parse() 会直接撑爆内存(OOM)。

  • 流式解析 (Streaming JSON)

    • 原理:不像传统解析器那样一次性把整个文件读入内存,而是像流水一样,读到一个节点处理一个。

    • 工具:Java 里的 Jackson Streaming API,Node.js 里的 JSONStream

  • 分片加载策略

    • 不要一次性返回所有数据。利用分页(Pagination)或无限滚动(Infinite Scroll)机制,将大 JSON 拆解为多个小片段。

5.3 二进制序列化变体

当带宽和存储成为瓶颈时,JSON 的文本特性反而成了缺点。

变体 特点 应用场景
BSON 二进制存储,支持更多类型(如 Date, BinData) MongoDB 的默认存储格式
MessagePack 极度紧凑,体积比 JSON 小得多,速度更快 分布式缓存、实时通信、IoT 设备

第六章:JSON 安全与最佳实践

6.1 安全风险分析

  • JSON 注入攻击 (JSON Injection)

    • 类似于 SQL 注入。如果程序通过简单的字符串拼接构造 JSON,攻击者可能插入恶意键值对来篡改逻辑。

    • 防御:永远使用官方序列化库,严禁手动拼接字符串。

  • 反序列化漏洞

    • 某些语言(如 Java)的解析库如果配置不当,攻击者可以通过特定的 JSON payload 触发服务器执行恶意代码。

    • 防御:禁用自动类型识别功能,限制可实例化的类。

  • 敏感信息泄露

    • 错误案例:直接把 User 对象(含 password_hash)序列化后发给前端。

    • 方案:使用数据传输对象(DTO)或在序列化时配置 @JsonIgnore (Java) 等注解。

6.2 最佳实践 Checklist (收藏必备)

  • Content-Type:后端返回时必须明确指定 application/json; charset=utf-8

  • 键名一致性:整个项目组应统一使用 snake_case(下划线)或 camelCase(驼峰),切忌混用。

  •  容错性:解析时务必包裹 try-catch。不要因为一条脏数据导致整个应用崩溃。


第七章:开发者工具箱 (资源推荐)

为了提高开发效率,这几个神器你必须知道:

7.1 在线调试工具

  • JSONLint:最经典的格式校验和格式化工具。

  • JSON Hero:它能把 JSON 变成像 Finder/文件管理器一样的界面,支持搜索和类型预览,非常适合查看巨大的 JSON。

7.2 编辑器插件 (VS Code)

  • JSON Crack:可以将 JSON 数据实时转换成思维导图/树状图,一眼看清嵌套关系。

  • Prettier:一键格式化,让你的 JSON 排版美观。

7.3 命令行神器:jq

如果你在 Linux/macOS 下工作,jq 是处理 JSON 的神。

  • 提取字段cat data.json | jq '.user.name'

  • 过滤列表cat products.json | jq '.[] | select(.price > 100)'

  • 格式化输出jq '.' filename.json

“JSON 并不是一种复杂的编程技术,它更像是一种沟通的艺术。学会如何优雅地组织、传输和校验数据,是你通往高级开发者之路的必经逻辑。”

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐