Skip to content

JSON 速查表

用于数据交换的轻量级数据格式。

01

入门

基本结构

JSON 支持 6 种数据类型:字符串、数字、布尔、null、数组和对象。键必须是双引号字符串。JSON 与语言无关,人和机器都易于读写。

json
{
  "name": "Alice",
  "age": 30,
  "isStudent": false,
  "height": 1.65,
  "nullValue": null,
  "hobbies": ["reading", "coding", "music"],
  "address": {
    "city": "NYC",
    "zip": "10001"
  }
}

JSON 语法规则

JSON 语法严格:键和字符串只能用双引号,逗号分隔元素,禁止尾随逗号。整个文档必须是单个 JSON 值。标准 JSON 不支持注释——如需注释,使用预处理器或 JSON5。

json
{
  "key": "value",          // key MUST be a double-quoted string
  "nested": { "a": 1 },    // objects use { } with comma-separated pairs
  "list": [1, 2, 3]        // arrays use [ ] with comma-separated values
}

// Rules:
// - Double quotes only for strings and keys (no single quotes)
// - Comma separates members; NO trailing comma
// - The whole document is ONE value (usually an object or array)
// - No comments allowed in standard JSON

JSON 中的注释

标准 JSON 禁止注释。常见变通方法:添加 '_comment' 字段(代码忽略)、使用 JSONC/JSON5(VS Code 等工具支持),或用 comment-json、JSON.minify 等库在解析前剥离注释。

json
// Standard JSON does NOT allow comments.

// Workaround 1: include a descriptive field
{
  "_comment": "This is a config file for the app",
  "port": 8080
}

// Workaround 2: use JSON5 or JSONC (VS Code settings)
{
  // line comment
  "port": 8080 /* block comment */
}

// Workaround 3: strip comments before parsing
// (e.g., JSON.minify, comment-json npm package)

空白与格式化

字符串外的空白无意义——紧凑形式和美化形式解析结果相同。紧凑 JSON 节省带宽;美化形式(常用 2 空格缩进)提升可读性和 diff 友好度。大多数序列化器提供 'pretty' 选项。

json
// These are all equivalent:

{"a":1,"b":2}                       // compact (no whitespace)

{ "a": 1, "b": 2 }                  // readable

{
  "a": 1,
  "b": 2
}                                   // pretty-printed

// Whitespace between tokens is insignificant.
// Use compact for transmission, pretty for humans.

文件扩展名与 MIME 类型

标准扩展名是 .json,MIME 类型是 application/json。JSONC、JSON5、GeoJSON、NDJSON 等变体有各自约定。始终使用 UTF-8 编码,不推荐使用 BOM。

json
// File extensions:
//   .json    standard JSON
//   .jsonc   JSON with comments (VS Code, TypeScript config)
//   .json5   JSON5 (relaxed syntax)
//   .geojson GeoJSON (geographic data)
//   .ndjson  Newline-Delimited JSON (JSON Lines)
//   .har     HTTP Archive (JSON-based)

// MIME type:
Content-Type: application/json

// Older/alternate MIME types (avoid):
//   text/json          (non-standard)
//   application/x-json (non-standard)

// UTF-8 is the default and recommended encoding.

JSON 值类别

JSON 值分为六种类型:字符串、数字、布尔、null、数组、对象。数组和对象是结构化类型(可容纳其他值),其余是基元类型。合法的 JSON 文档是一个值——通常是对象或数组,但单独的数字或字符串也合法。

json
// A JSON value is exactly one of these six types:

"hello"                 // string
42                      // number
3.14                    // number
true                    // boolean
false                   // boolean
null                    // null
[1, 2, 3]               // array
{ "a": 1 }              // object

// Structured types: array, object
// Primitive types: string, number, boolean, null
// A standalone JSON document is a single value of any type.
02

数据类型

字符串类型

JSON 字符串是双引号包裹的 Unicode 文本。常见转义:\"(引号)、\\(反斜杠)、\/(斜杠)、\n、\t、\r、\b、\f,以及任意码点的 \uXXXX。不允许用单引号作为字符串分隔符。

json
{
  "single": "double quotes only",
  "empty": "",
  "escaped": "He said \"hi\" and C:\\Users",
  "unicode": "Cafu00e9 \u00e9 \u1F600",
  "multiline": "line1\nline2\ttabbed"
}

// Strings MUST use double quotes.
// Single quotes are NOT valid in JSON.

数字类型

JSON 数字遵循 IEEE 754 双精度的子集:整数、小数和科学计数法(如 6.022e23)。禁止前导零(007 非法)。NaN、Infinity、-Infinity 不合法——需要时用 null 或字符串表示。

json
{
  "integer": 42,
  "negative": -7,
  "float": 3.14,
  "zero": 0,
  "scientific": 6.022e23,
  "small": 1.5e-10
}

// Numbers are NOT quoted.
// No leading zeros (007 is invalid).
// No NaN, Infinity, or -Infinity (not valid JSON).

布尔类型

JSON 布尔是字面关键字 true 和 false(小写、不加引号)。加引号的 'true'/'false' 是字符串。JSON 语法层没有 0/1 或 yes/no 作为布尔的概念——需要在应用代码中转换。

json
{
  "enabled": true,
  "disabled": false,
  "flag": true
}

// Booleans are the bare keywords true and false.
// They are NOT quoted ("true" is a string).
// 0/1, yes/no, on/off are NOT booleans in JSON.

Null 类型

JSON null 是字面关键字 null(不加引号),表示有意缺失值。它不同于空字符串 ''、0、false、缺失键或空集合。许多语言将 null 映射为 None/nil/null。

json
{
  "middleName": null,
  "deletedAt": null,
  "optional": null
}

// null is a bare keyword (unquoted).
// "null" (quoted) is a string, not null.
// null represents the intentional absence of value.

数组类型

JSON 数组是 [ ] 包裹的有序列表,逗号分隔,从 0 开始索引。可容纳任意 JSON 值,包括混合类型和嵌套数组/对象。空数组 [] 合法。顺序被保留且有意义。

json
{
  "numbers": [1, 2, 3],
  "mixed": [1, "two", true, null],
  "nested": [[1, 2], [3, 4]],
  "objects": [
    { "id": 1 },
    { "id": 2 }
  ],
  "empty": []
}

// Arrays are ordered, zero-indexed, and can hold mixed types.

对象类型

JSON 对象是 { } 包裹的无序键值对集合。键必须是唯一的双引号字符串;值可以是任意 JSON 类型。虽然对象概念上无序,但大多数解析器保留插入顺序——不要依赖顺序做正确性保证。

json
{
  "user": {
    "id": 1,
    "name": "Alice",
    "roles": ["admin", "user"],
    "active": true
  },
  "empty": {}
}

// Objects are unordered collections of key/value pairs.
// Keys MUST be unique strings (double-quoted).
// Values can be any JSON type.
03

字符串

字符串基础

JSON 字符串是双引号包裹的 Unicode 字符序列。正斜杠可转义(\/)但非必须——在 <script> 标签中嵌入 JSON 时有用。空字符串合法。

json
{
  "name": "Alice",
  "email": "[email protected]",
  "url": "https://example.com/path?q=1",
  "path": "C:\\Users\\alice",
  "empty": ""
}

// Strings are double-quoted Unicode text.
// Forward slash may be escaped as \/ but does not have to be.

转义序列

JSON 支持这些转义:\"(引号)、\\(反斜杠)、\/(斜杠)、\b(退格)、\f(换页)、\n(换行)、\r(回车)、\t(制表符)、\uXXXX(Unicode 码点)。其他反斜杠序列均非法。

json
{
  "quote": "She said \"hello\"",
  "backslash": "C:\\Users\\name",
  "newline": "line1\nline2",
  "tab": "col1\tcol2",
  "carriage": "a\rb",
  "backspace": "a\bb",
  "formfeed": "a\fb",
  "slash": "a\/b"
}

// Valid escapes: \" \\ \/ \b \f \n \r \t \uXXXX

Unicode 字符

用 \uXXXX 表示任意 Unicode 码点。U+FFFF 以上的字符(如许多 emoji)需要代理对:两个 \u 转义。现代解析器也接受原始 UTF-8 字符直接出现在字符串中——\uXXXX 主要用于安全或无法输入字符时。

json
{
  "eacute": "Caf\u00e9",
  "euro": "Price: \u20ac10",
  "emoji": "Smile \ud83d\ude00",
  "chinese": "\u4f60\u597d",
  "raw": "Cafu00e9 u00e9 \u00e9"
}

// \uXXXX encodes a code point in the Basic Multilingual Plane.
// Surrogate pairs (two \u escapes) encode characters above U+FFFF.
// Modern parsers also accept the raw UTF-8 character directly.

字符串中的特殊字符

JSON 字符串内必须始终转义双引号和反斜杠(\" 和 \\)。其他特殊字符(HTML、SQL、正则)遵循各自规则,但 JSON 只要求转义 \" 和 \\(以及控制字符)。字面反斜杠写作 \\。

json
{
  "html": "<div class=\"x\">Hi</div>",
  "sql": "SELECT * FROM t WHERE name='O''Brien'",
  "regex": "^\\d{3}-\\d{4}$",
  "json": "{ \"k\": \"v\" }",
  "cmd": "echo \"hello\""
}

// Backslash is the universal escape character.
// To include a literal backslash, write \\.

多行字符串(变通方案)

JSON 字符串不能包含字面换行——必须转义为 \n。多行内容可嵌入 \n、使用行字符串数组,或改用 YAML/JSON5 等支持多行字符串的格式。字面未转义换行是语法错误。

json
// JSON does NOT support real multi-line strings.
// The following is INVALID:
// { "text": "line1
// line2" }

// Workaround 1: escape the newline
{ "text": "line1\nline2" }

// Workaround 2: array of lines
{ "lines": ["line1", "line2"] }

// Workaround 3: JSON5 allows continued strings (still single logical line)

常见字符串陷阱

常见字符串错误:用单引号、留下尾随逗号、忘记转义内部双引号、嵌入字面控制字符(制表/换行)而非 \t/\n 转义。严格解析器会拒绝所有这些。

json
// WRONG: single quotes
// { 'name': 'Alice' }

// WRONG: trailing comma
// { "a": 1, }

// WRONG: unescaped quote
// { "msg": "He said "hi"" }

// WRONG: literal tab/newline in string
// { "x": "a<TAB>b" }

// RIGHT:
{ "name": "Alice", "msg": "He said \"hi\"" }
04

数字

整数与浮点数

JSON 只有一种数字类型,涵盖整数和浮点数。语法层没有单独的整数类型——语言绑定可能根据值和库将大整数映射为 int、long、float 或 decimal。

json
{
  "count": 100,
  "negative": -42,
  "temperature": -273.15,
  "pi": 3.14159,
  "zero": 0,
  "negativeZero": -0
}

// Integers and floats use the same number type.
// JSON does not distinguish int from float at the syntax level.

科学计数法

JSON 支持科学计数法:尾数后跟 e 或 E 和可选带符号指数(6.022e23 = 6.022 * 10^23)。e 和 E 均可接受。这对科学数据中的极大或极小数至关重要。

json
{
  "avogadro": 6.022e23,
  "planck": 6.626e-34,
  "speedOfLight": 2.998e8,
  "small": 1.5E-10
}

// e or E is allowed (case-insensitive).
// 6.022e23 means 6.022 * 10^23.
// The exponent may be negative.

数字精度

JSON 数字通常被解析为 IEEE 754 双精度,因此 JavaScript 中 2^53-1(9007199254740991)以上的整数会丢失精度。0.1 等小数无法精确表示。对货币或任意精度整数,用字符串编码并在代码中使用 Decimal/BigInteger 类型。

json
{
  "big": 9007199254740993,
  "decimal": 0.1,
  "sum": 0.1,
  "money": 19.99
}

// JavaScript stores numbers as IEEE 754 doubles.
// Integers are safe up to 2^53 - 1 (9007199254740991).
// 0.1 + 0.2 === 0.30000000000000004 (float precision loss).

// For money or big integers, parse as string or use a Decimal type.

特殊值(不允许)

标准 JSON 不允许 NaN、Infinity、-Infinity。变通方法:用 null 表示 NaN,将 Infinity 编码为字符串,或用有限哨兵值。某些序列化器(Python json 默认、JSON5)作为扩展输出这些,但产物非标准,严格解析器会拒绝。

json
// NaN, Infinity, and -Infinity are NOT valid JSON.

// INVALID:
// { "x": NaN }
// { "y": Infinity }
// { "z": -Infinity }

// Common workarounds:
{
  "x": null,           // represent NaN/null
  "y": "Infinity",     // encode as a string
  "z": 1.7976931348623157e308  // use a finite max
}

// Many serializers (e.g., Python json) accept these as extensions
// but the output is not standard JSON.

数字格式

合法 JSON 数字:可选负号、整数部分(除 0 外无前导零)、可选小数部分、可选指数。十六进制(0x)、二进制(0b)、八进制、下划线、前导 +、前导零、两侧无数字的点均非法。

json
// VALID JSON numbers:
42
-7
0
3.14
-0.5
6.022e23
1.5E-10
100.00

// INVALID:
007        // leading zero
.5         // no leading digit
5.         // no trailing digit after dot
+5         // leading plus sign
0x1F       // hex
0b101      // binary
1_000      // underscores

大数与 BigInt

对 2^53-1 以上的值(如 Twitter snowflake ID、64 位整数、大额余额),用字符串编码以避免精度丢失。若必须在 JSON.parse 中用 reviver 转换数字为 BigInt,注意 BigInt 无法被 JSON.stringify 重新序列化(需 replacer)——传输时用字符串更安全。

json
{
  "snowflake": "1234567890123456789",
  "timestamp": 1696000000000,
  "balance": "99999999999999999999"
}

// Numbers above 2^53-1 lose precision in JS.
// Use STRINGS for IDs, snowflakes, and big integers.

// In JavaScript, parse with a reviver:
// JSON.parse(str, (k, v) =>
//   typeof v === "number" && v > Number.MAX_SAFE_INTEGER
//     ? BigInt(v) : v);  // careful: BigInt can't be in JSON.stringify

// Better: keep them as strings on the wire.
05

布尔与 Null

布尔值

JSON 布尔是字面关键字 true 和 false。加引号的 'true'/'false' 是字符串。JSON 语法层没有 truthy/falsy 概念——1、0、yes、no、on、off 都是字符串或数字,不是布尔。在应用代码中转换。

json
{
  "enabled": true,
  "disabled": false,
  "isPublic": true,
  "isActive": false
}

// Only two boolean values: true and false (lowercase, unquoted).
// "true" (quoted) is a STRING, not a boolean.
// 1/0, yes/no, on/off are NOT booleans.

Null 的含义

JSON null 表示有意缺失值。它不同于缺失键(键不存在)、空字符串 ''、0、false 或空集合。字段存在但无值时用 null;字段本身不适用时省略键。

json
{
  "middleName": null,
  "deletedAt": null,
  "parent": null,
  "optional": null
}

// null means "no value" or "intentionally absent".
// Distinct from:
//   - missing key (key not present at all)
//   - empty string ""
//   - 0 or false
//   - empty array [] or object {}

Null、空与缺失的区别

三种不同状态:键带空值("")、键显式为 null、缺失键。JavaScript 中 undefined 表示键缺失,而 null 表示存在但无值。API 应文档说明可选字段使用哪种约定。

json
{
  "name": "Alice",
  "nickname": "",          // empty string (present, empty)
  "middleName": null,      // explicit null (present, no value)
  // "maidenName"           // missing (key not in object)
}

// In JavaScript:
//   obj.nickname === ""           // true
//   obj.middleName === null       // true
//   obj.maidenName === undefined  // true (key absent)
//   "maidenName" in obj           // false

// Choose deliberately: null vs "" vs missing.

在条件中使用布尔值

使用 JSON 布尔时,若需区分 false 和缺失,优先用严格比较(=== true)而非 truthy 检查。API 响应中即使为 false 也应包含布尔字段——省略会迫使客户端猜测默认值。

json
{
  "isAdmin": true,
  "canEdit": false,
  "active": true
}

// In application code (JavaScript):
// if (user.isAdmin) { ... }       // truthy check
// const canEdit = user.canEdit === true;  // strict boolean check

// Be careful: a missing 'canEdit' key is undefined (falsy),
// but explicit false is also falsy. Distinguish if needed.

// API design: always send the boolean, even when false.

常见陷阱

常见陷阱:加引号的 true/false/null 变成字符串;用 True/TRUE/None(Python 风格)或大小写错误为非法;JSON 没有 undefined(只有 null)。唯一合法形式是小写不加引号的关键字 true、false、null。

json
// Pitfall 1: quoting booleans/null
// { "x": "true" }   -> x is a STRING, not a boolean
// { "y": "null" }   -> y is a STRING, not null

// Pitfall 2: wrong case
// { "x": True }     -> INVALID (Python-style, not JSON)
// { "x": TRUE }     -> INVALID
// { "x": None }     -> INVALID

// Pitfall 3: confusing null with undefined
//   null exists in JSON; undefined does NOT.

// Correct:
{ "x": true, "y": null }
06

数组

数组基础

JSON 数组是 [ ] 包裹的有序、从 0 开始索引的列表,逗号分隔值。空数组和单元素数组合法。顺序有意义且被解析器保留。不允许尾随逗号。

json
{
  "numbers": [1, 2, 3, 4, 5],
  "strings": ["a", "b", "c"],
  "booleans": [true, false, true],
  "empty": [],
  "single": [42]
}

// Arrays are ordered, zero-indexed lists in [ ].
// Elements are separated by commas (no trailing comma).
// Empty arrays [] and single-element arrays are valid.

混合类型数组

JSON 数组可合法容纳混合类型([1, 'two', true, null])。这合法但通常表明 schema 设计薄弱。同质数组(全字符串或全对象)更易验证、文档化和消费。用 schema 强制元素类型。

json
{
  "mixed": [1, "two", true, null, 3.14],
  "nested": [[1, 2], "x", { "a": 1 }]
}

// JSON arrays CAN hold values of different types.
// This is valid but often a sign of weak schema design.
// Prefer homogeneous arrays for clarity and validation.

嵌套数组

数组可任意深度嵌套,适用于矩阵、网格和树结构。JSON 不强制嵌套数组等长('ragged' 数组合法)。若需矩形矩阵,用 schema 或应用代码强制。

json
{
  "matrix": [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
  ],
  "ragged": [[1, 2], [3, 4, 5], [6]]
}

// Arrays can nest arbitrarily deep.
// JSON does not enforce rectangular shape—use a schema if needed.

对象数组

对象数组是记录列表(用户、产品、帖子)最常见的模式。每个元素通常形状相同,但 JSON 不强制——用 schema(JSON Schema 'items')验证所有元素一致。

json
{
  "users": [
    { "id": 1, "name": "Alice" },
    { "id": 2, "name": "Bob" },
    { "id": 3, "name": "Carol" }
  ],
  "empty": []
}

// A very common pattern: a list of records.
// Each element is an object with the same shape.

空数组和单元素数组

空数组 [] 和单元素数组合法。API 设计中应区分 [](存在、空列表)、null(存在、无列表)和缺失键(字段不适用)。'无项目' 时返回 [] 通常比 null 更友好。

json
{
  "empty": [],
  "single": [42],
  "tags": [],
  "items": ["one"]
}

// Both forms are valid.
// Distinguish [] from null and from a missing key:
//   "tags": []      -> present, empty list
//   "tags": null    -> present, no list
//   // (no tags)    -> missing key

代码中访问数组

解析后 JSON 数组变为语言的原生数组/列表(JS Array、Python list、Java List 等)。使用标准索引访问、长度和迭代。边界和类型安全由你负责——JSON 本身不强制元素类型。

json
{
  "list": ["a", "b", "c"]
}

// JavaScript:
//   const arr = JSON.parse(json).list;
//   arr[0]            // "a"
//   arr.length        // 3
//   arr.includes("b") // true
//   arr.map(x => x.toUpperCase())  // ["A", "B", "C"]

// Python:
//   data = json.loads(json_str)
//   data["list"][0]   # "a"
//   len(data["list"]) # 3
07

对象

对象基础

JSON 对象是 { } 包裹的无序键值对集合。键必须是双引号字符串;值可以是任意 JSON 类型。逗号分隔键值对,无尾随逗号。对象是最常见的顶层 JSON 结构。

json
{
  "id": 1,
  "name": "Alice",
  "email": "[email protected]",
  "active": true
}

// Objects are unordered { } collections of key/value pairs.
// Keys MUST be double-quoted strings.
// Pairs are comma-separated (no trailing comma).

键命名规则

JSON 键可以是任意双引号字符串,包括空、含空格、点或数字。但为 API 清晰起见,统一使用 camelCase、snake_case 或 kebab-case。公开 API 中避免空格、点(与路径语法冲突)和空键。

json
{
  "simple": "ok",
  "with-dash": "ok",
  "with_underscore": "ok",
  "with.dot": "ok",
  "with space": "ok (but avoid)",
  "123numeric": "ok (but avoid)",
  "": "empty key is valid"
}

// Keys are arbitrary strings (double-quoted).
// Convention: use camelCase, snake_case, or kebab-case consistently.
// Avoid empty keys and keys with spaces/dots in APIs.

嵌套对象

对象可任意深度嵌套,适用于层次数据。深嵌套合法但会损害可读性并增加耦合。公开 API 优先用更扁平的结构或引用(ID)而非深嵌套树。

json
{
  "user": {
    "name": "Alice",
    "address": {
      "street": "123 Main St",
      "city": "NYC",
      "geo": { "lat": 40.7, "lng": -74.0 }
    }
  }
}

// Objects can nest arbitrarily deep.
// Deep nesting is valid but can hurt readability—flatten when sensible.

带数组的对象

结合对象(键控字段)和数组(有序列表)可建模几乎所有真实数据。常见模式是对象包裹嵌套对象数组(带订单的用户)。用 schema 文档化和验证预期形状。

json
{
  "user": {
    "name": "Alice",
    "roles": ["admin", "user"],
    "orders": [
      { "id": 1, "total": 19.99 },
      { "id": 2, "total": 5.99 }
    ]
  }
}

// Combining objects and arrays models most real-world data.

成员顺序

JSON 规范将对象视为无序。实践中大多数现代解析器(JavaScript V8、Python 3.7+、Java LinkedHashMap)保留插入顺序,但不应依赖此做正确性保证。若顺序对哈希或签名重要,显式排序键。

json
{
  "z": 1,
  "a": 2,
  "m": 3
}

// JSON objects are SPECIFIED as unordered.
// In practice, most parsers (JS, Python 3.7+) preserve insertion order.
// DO NOT rely on order for correctness—sort keys if order matters.

// Sorting keys (e.g., for stable hashing):
//   JSON.stringify(obj, Object.keys(obj).sort())

重复键

JSON 规范未禁止重复键,但其行为未定义——大多数解析器保留最后一个值,部分保留第一个。重复键是微妙 bug 的常见来源。JSON Schema 可强制 uniqueKeys;linter 和严格解析器可拒绝它们。

json
// Technically valid JSON, but behavior is UNDEFINED:
{
  "name": "Alice",
  "name": "Bob"
}

// Most parsers keep the LAST value ("Bob"),
// but some keep the first. Avoid duplicate keys!

// JSON Schema (draft 2019-09+) has 'uniqueKeys' to forbid them.
// JSON.parse in JS keeps the last value (object property override).
08

嵌套结构

深度嵌套

JSON 允许任意嵌套深度,但极深结构损害可读性并可能触及解析器限制(许多解析器施加深度上限,如 1000,以防拒绝服务)。对深层层次数据,优先用更扁平的结构加 ID/引用。

json
{
  "a": {
    "b": {
      "c": {
        "d": {
          "e": { "value": 42 }
        }
      }
    }
  }
}

// Nesting depth is theoretically unlimited.
// Many parsers impose a limit (e.g., 1000) to prevent DoS.
// Deep nesting hurts readability—consider flattening or references.

真实示例

真实 JSON 混合对象和数组来建模实体及其关系。此订单示例嵌套 customer、items(对象数组)和 shipping。用 schema 文档化形状;保持适中嵌套以利可读性。

json
{
  "order": {
    "id": "ord-123",
    "customer": {
      "id": "cus-1",
      "name": "Alice",
      "email": "[email protected]"
    },
    "items": [
      { "sku": "A1", "qty": 2, "price": 9.99 },
      { "sku": "B2", "qty": 1, "price": 19.99 }
    ],
    "shipping": {
      "address": { "city": "NYC", "zip": "10001" },
      "method": "express"
    },
    "total": 39.97
  }
}

树结构

树递归建模:每个节点有值和子节点数组。此模式见于文件系统、组织架构图和 AST。注意循环——JSON 无引用语法,故循环图必须用 ID 或序列化为带父指针的扁平列表。

json
{
  "name": "root",
  "children": [
    {
      "name": "child-a",
      "children": [
        { "name": "grandchild-1", "children": [] },
        { "name": "grandchild-2", "children": [] }
      ]
    },
    { "name": "child-b", "children": [] }
  ]
}

// Recursive structures: a node contains an array of child nodes.

访问嵌套值

访问深度嵌套值在中间键缺失时有 TypeError/KeyError 风险。用可选链(JS ?. 和 ??)或链式 .get()(Python)加默认值。lodash.get 或 jq 等库简化深度提取并提供默认值。

json
{
  "user": { "address": { "city": "NYC" } }
}

// JavaScript (optional chaining):
//   const city = data?.user?.address?.city ?? "unknown";

// Python:
//   city = data.get("user", {}).get("address", {}).get("city", "unknown")

// Deep access without guards throws on missing keys.
// Use optional chaining or a helper like lodash.get.

扁平化嵌套数据

扁平化嵌套对象(如用 'user.name' 代替 { user: { name } })简化环境变量、表单字段和搜索索引的访问。权衡是丢失结构和更难往返。用库(flat、lodash)扁平化/还原。

json
// Nested form:
{ "user": { "name": "Alice", "city": "NYC" } }

// Flattened form (dot notation):
{ "user.name": "Alice", "user.city": "NYC" }

// Flattened form (separate keys):
{ "userName": "Alice", "userCity": "NYC" }

// Use cases: environment variables, form fields, search indexing.
// Trade-off: simpler access vs. loss of structure.
09

JSON Schema

Schema 基础

JSON Schema 是描述和验证 JSON 文档的 JSON 词汇。根声明 $schema(草案版本)和 type。properties 列出字段及其类型;required 列出必填键。Ajv(JS)或 jsonschema(Python)等验证器检查一致性。

json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/user.json",
  "title": "User",
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "age": { "type": "integer", "minimum": 0 }
  },
  "required": ["name"]
}

类型验证

'type' 关键字验证值的 JSON 类型:string、number、integer、boolean、null、array、object。可以是单个类型或数组(如 ['string', 'null'] 表示可空可选字符串)。'integer' 匹配无小数部分的数字。

json
{
  "type": "object",
  "properties": {
    "name":   { "type": "string" },
    "age":    { "type": "integer" },
    "active": { "type": "boolean" },
    "score":  { "type": "number" },
    "tags":   { "type": "array", "items": { "type": "string" } },
    "meta":   { "type": "object" },
    "middle": { "type": ["string", "null"] }
  }
}

// 'type' can be a single type or an array of allowed types.

字符串约束

字符串约束:minLength、maxLength、pattern(正则)、enum(允许值)和 format(语义提示如 'email'、'uri'、'date-time'、'ipv4')。'format' 默认仅注解——验证器需显式开启才会强制。用 pattern 做严格正则验证。

json
{
  "type": "object",
  "properties": {
    "email": {
      "type": "string",
      "format": "email",
      "maxLength": 254
    },
    "username": {
      "type": "string",
      "pattern": "^[a-zA-Z0-9_]{3,20}$",
      "minLength": 3,
      "maxLength": 20
    },
    "bio": { "type": "string", "maxLength": 500 }
  }
}

// 'format' is a semantic hint (email, uri, date, ipv4).
// 'pattern' is a regular expression.

数字约束

数字约束:minimum、maximum(含)、exclusiveMinimum、exclusiveMaximum、multipleOf。对 'integer' 类型,值必须无小数部分。组合约束建模范围(如 1 到 5 的评分)。

json
{
  "type": "object",
  "properties": {
    "age":   { "type": "integer", "minimum": 0, "maximum": 150 },
    "price": { "type": "number", "minimum": 0, "exclusiveMinimum": 0 },
    "rating":{ "type": "integer", "minimum": 1, "maximum": 5 },
    "count": { "type": "integer", "multipleOf": 5 }
  }
}

// minimum/maximum are inclusive;
// exclusiveMinimum/exclusiveMaximum are exclusive.

对象与数组约束

数组约束:items(元素 schema)、minItems、maxItems、uniqueItems。对象约束:required(必填键)、properties(字段 schema)、additionalProperties(false 禁止额外键,或为其指定 schema)、minProperties、maxProperties。

json
{
  "type": "object",
  "properties": {
    "id":   { "type": "integer" },
    "tags": {
      "type": "array",
      "items": { "type": "string" },
      "minItems": 1,
      "maxItems": 10,
      "uniqueItems": true
    }
  },
  "required": ["id"],
  "additionalProperties": false
}

// minItems/maxItems/uniqueItems constrain arrays.
// required lists mandatory keys; additionalProperties
// controls whether extra keys are allowed.

高级验证

高级 JSON Schema:oneOf/anyOf/allOf 组合子 schema;$ref 引用可复用定义;if/then/else 应用条件验证;const 要求精确值;enum 列出允许值。这些让你表达丰富约束和可复用类型。

json
{
  "oneOf": [
    { "type": "string" },
    { "type": "integer" }
  ],
  "definitions": {
    "address": {
      "type": "object",
      "properties": { "city": { "type": "string" } }
    }
  },
  "properties": {
    "home": { "$ref": "#/definitions/address" },
    "work": { "$ref": "#/definitions/address" }
  },
  "if":   { "properties": { "type": { "const": "vip" } } },
  "then": { "required": ["discount"] }
}

// oneOf/anyOf/allOf combine schemas.
// $ref reuses definitions; if/then/else is conditional.
10

JSONPath

JSONPath 语法

JSONPath 是 JSON 查询语言,灵感来自 XPath。'$' 是根,'.' 选子节点,'[index]' 选数组元素,'*' 是通配符,'..' 是递归下降。jsonpath-plus(JS)或 jsonpath-ng(Python)等库实现它。

json
// JSONPath queries JSON like XPath queries XML.

// Sample data:
{
  "store": {
    "book": [
      { "category": "fiction", "price": 12.99 },
      { "category": "web",     "price": 29.99 }
    ]
  }
}

// Common JSONPath expressions:
$.store.book[0].category      // "fiction"
$.store.book[*].price         // [12.99, 29.99]
$..price                      // all prices anywhere
$.store..category             // all categories under store

根与子节点

'$' 引用根。'.' 按名选子节点;'[]' 是括号替代形式,可处理含点、空格或引号的键。'[index]' 选数组元素(0 开始);部分实现支持负索引从末尾计数。

json
// '$' = root object/array
// '.' or '[]' = child

$.user.name              // dot notation
$['user']['name']        // bracket notation (use for special chars)
$.users[0]               // first element of users array
$.users[-1]              // last element (some implementations)

// Use bracket notation when keys contain dots, spaces, or quotes:
$['user.name']
$['first name']

递归下降

'..'(递归下降)匹配任意深度的键或元素。'$..price' 返回无论何处出现的每个 'price' 值。'$..*' 返回每个节点。当不知道确切路径时,这对搜索大型或深嵌套 JSON 非常有用。

json
{
  "a": { "b": { "c": 1 }, "c": 2 }
}

// '..' searches at all depths:
$..c                      // [1, 2] (all 'c' keys anywhere)
$..a                      // all 'a' keys
$..*                      // every node (everything)

// Useful for finding a key without knowing the exact path:
$..price                  // every price, no matter how nested

过滤表达式

过滤器用 [?(表达式)],'@' 指当前项。支持的运算符因实现而异,但通常包括 ==、!=、<、<=、>、>=、&&(与)、||(或),有时还有 =~ 正则。length()、contains() 等函数增加能力。

json
// Filter with [?(expression)]:

$.store.book[?(@.price < 20)]            // books under 20
$.store.book[?(@.category == 'web')]     // web books
$.store.book[?(@.price < 30 && @.category == 'web')]

// '@' refers to the current item being filtered.
// Operators: == != < <= > >= && || =~ (regex in some impls)
// Functions: length(), contains(), matches()

通配符

'*' 是通配符,匹配对象所有子节点或数组所有元素。'$.users[*].name' 返回每个用户的 'name'。'$..*' 返回每个节点。结果以匹配数组返回,即使只有一个。

json
{
  "users": [
    { "name": "Alice", "age": 30 },
    { "name": "Bob",   "age": 25 }
  ]
}

// '*' matches all elements/children:
$.users[*]               // all user objects
$.users[*].name          // ["Alice", "Bob"]
$.users[0].*             // all values of first user: ["Alice", 30]
$..*                     // every node in the document

// Wildcards return arrays of matches.

常见函数与示例

JSONPath 函数因实现而异:length()、min()、max()、avg()、sum()、contains()、matches() 常见。组合过滤器和递归下降可做强大查询。命令行工作首选 jq,它使用略不同的语法。

json
// length(): array length or string length
$.users.length()                    // number of users
$.store.book[?(@.title.length() > 10)]

// min(), max(), avg(), sum() (some implementations)
$.store.book..price.min()

// Realistic query: titles of cheap web books
$.store.book[?(@.price < 20 && @.category == 'web')].title

// Tools: jq (CLI), jsonpath-plus (JS), jsonpath-ng (Python),
//        Jayway (Java), GoJSONQ (Go)
11

JSON 与 XML 及 YAML

JSON 与 XML 语法

JSON 更轻量(无闭合标签,数字/布尔/null 原生类型)且直接映射大多数语言数据结构。XML 更重但更丰富:属性、命名空间、混合内容、schema(XSD)和转换(XSLT)。JSON 主导 Web API;XML 持续用于企业/SOAP。

json
// JSON:
{
  "name": "Alice",
  "age": 30,
  "hobbies": ["reading", "coding"]
}

<!-- XML: -->
<person>
  <name>Alice</name>
  <age>30</age>
  <hobbies>
    <hobby>reading</hobby>
    <hobby>coding</hobby>
  </hobbies>
</person>

// JSON: lighter, no closing tags, types (number/boolean/null).
// XML:  heavier, supports attributes, namespaces, mixed content.

JSON 与 YAML 语法

YAML 用缩进代替大括号/引号,支持注释、多行字符串和锚点/别名。JSON 更严格(需引号、无注释)但更快更普及。YAML 是 JSON 超集——每个合法 JSON 文件也是合法 YAML。

json
# YAML:
name: Alice
age: 30
hobbies:
  - reading
  - coding

// JSON (equivalent):
{
  "name": "Alice",
  "age": 30,
  "hobbies": ["reading", "coding"]
}

// YAML: no quotes/braces, indentation-based, supports comments.
// JSON: stricter, faster to parse, ubiquitous in APIs.

JSON 转 YAML

因 YAML 是 JSON 超集,JSON 转 YAML 很直接。Python 的 yaml.dump 和 Node 的 js-yaml 处理。结果用缩进且(大多)无引号。YAML 的注释和多行字符串无法从 JSON 往返(JSON 没有这些)。

json
// JSON input:
{ "name": "Alice", "roles": ["admin", "user"] }

// YAML output:
name: Alice
roles:
  - admin
  - user

// Python:
//   import yaml, json
//   yaml.dump(json.loads(json_str), sort_keys=False)

// Node.js:
//   const yaml = require('js-yaml');
//   yaml.dump(JSON.parse(jsonStr));

YAML 转 JSON

简单 YAML 转 JSON 可行,但会丢失 YAML 特有特性:注释、锚点/别名、多文档流、标签和复杂键。用 yaml.safe_load 避免自定义标签的任意代码执行。结果为标准 JSON。

json
# YAML input:
server:
  host: localhost
  port: 8080
  debug: true

// JSON output:
{
  "server": {
    "host": "localhost",
    "port": 8080,
    "debug": true
  }
}

// Python:
//   import yaml, json
//   json.dumps(yaml.safe_load(yaml_str), indent=2)

// Watch for YAML-specific features: anchors, tags, multi-docs.

数据建模差异

JSON 用对象和数组建模数据——无属性或命名空间。XML 增加属性、命名空间、混合内容和丰富 schema。YAML 增加注释、锚点和多文档支持。TOML 面向配置文件的表。按需选择:API(JSON)、文档(XML)、配置(YAML/TOML)。

json
// JSON: objects and arrays, no attributes.
//   Attribute-style metadata needs a convention (e.g., @_prefix).

// XML: elements + attributes, namespaces, mixed content.
//   <book id="b1" category="web"><title>...</title></book>

// YAML: maps, sequences, scalars, anchors, multi-doc.
//   Supports comments and multi-line strings natively.

// TOML: tables + key/value, designed for config files.
//   Best for configuration; not ideal for nested data.

何时使用各格式

JSON 用于 Web API 和 NoSQL 存储(通用、快速)。XML 用于企业服务、文档中心数据(SVG、XHTML)和丰富 schema。YAML 用于人写的配置(CI/CD、docker-compose),得益于注释和可读性。TOML 用于小型配置文件。按用例匹配格式。

json
// Use JSON when:
//   - building web/REST APIs (universal browser support)
//   - storing structured data (NoSQL databases)
//   - configuration with simple needs (package.json)

// Use XML when:
//   - enterprise/SOAP web services
//   - documents with mixed content (SVG, XHTML, DocBook)
//   - you need schemas, namespaces, or XSLT transforms

// Use YAML when:
//   - human-written config (CI/CD, docker-compose)
//   - you need comments and multi-line strings

// Use TOML when:
//   - small config files (Cargo, pyproject)
12

JavaScript 中的解析

JSON.parse

JSON.parse 将 JSON 字符串转为 JavaScript 值。接受任何合法 JSON 值(对象、数组、字符串、数字、布尔、null)。非法 JSON 抛出 SyntaxError。处理不可信输入时始终用 try/catch 包裹 JSON.parse。

json
// Parse a JSON string into a JavaScript value.
const json = '{"name":"Alice","age":30}';
const obj = JSON.parse(json);

console.log(obj.name); // "Alice"
console.log(obj.age);  // 30

// JSON.parse accepts a string only.
// Passing a number/boolean/object throws or coerces.
// JSON.parse("42")    === 42       (valid)
// JSON.parse("true")  === true     (valid)
// JSON.parse("null")  === null     (valid)
// JSON.parse(undefined) // throws SyntaxError

JSON.stringify

JSON.stringify 将 JavaScript 值序列化为 JSON 字符串。函数、Symbol 和 undefined 在对象中被省略,在数组中变为 null。BigInt 抛出 TypeError——先转为字符串。用第三个参数(space)美化输出。

json
// Serialize a JavaScript value to a JSON string.
const obj = { name: "Alice", age: 30 };
const json = JSON.stringify(obj);
// '{"name":"Alice","age":30}'

// Pretty-print with 2-space indent:
JSON.stringify(obj, null, 2);
// {
//   "name": "Alice",
//   "age": 30
// }

// Functions, Symbols, and undefined are omitted.
// BigInt throws; use a replacer or String() first.

Reviver 函数

JSON.parse 的 reviver 在解析期间变换值。它自底向上对每个键/值对调用(包括根,键为 '')。返回变换后的值,或 undefined 省略属性。适用于日期解析、BigInt 和自定义类型。

json
// JSON.parse accepts a 'reviver' to transform values.
const json = '{"date":"2024-01-15","count":"42"}';

const obj = JSON.parse(json, (key, value) => {
  if (key === "date") return new Date(value);
  if (key === "count") return Number(value);
  return value;
});

// obj.date is a Date object; obj.count is a number.

// Reviver is called bottom-up for every key, including the root.

Replacer 函数

JSON.stringify 的 replacer 在序列化期间过滤或变换值。作为函数时对每个键调用——返回 undefined 省略属性。作为数组时作为键白名单。适用于脱敏秘密和选择字段。

json
// JSON.stringify accepts a 'replacer' to filter/transform.
const obj = { name: "Alice", password: "secret", age: 30 };

// Replacer as a function:
const safe = JSON.stringify(obj, (key, value) => {
  if (key === "password") return undefined; // omit
  return value;
});
// '{"name":"Alice","age":30}'

// Replacer as an array (allowlist of keys):
JSON.stringify(obj, ["name", "age"]);
// '{"name":"Alice","age":30}'

美化输出

传 space 参数给 JSON.stringify 美化输出:数字(缩进深度)或字符串(如 '\t')。为稳定键序(用于哈希或签名),先排序键再序列化。可与 replacer 组合在美化时过滤字段。

json
const obj = { name: "Alice", age: 30 };

// Compact (default):
JSON.stringify(obj);
// '{"name":"Alice","age":30}'

// 2-space indent:
JSON.stringify(obj, null, 2);

// Tab indent:
JSON.stringify(obj, null, "\t");

// Combine replacer and indent:
JSON.stringify(obj, ["name", "age"], 2);

// To insert a stable key order, sort keys first:
const sorted = Object.keys(obj).sort()
  .reduce((acc, k) => (acc[k] = obj[k], acc), {});
JSON.stringify(sorted, null, 2);

错误处理

JSON.parse 对非法输入抛出 SyntaxError——处理不可信数据时始终用 try/catch。常见原因:尾随逗号、单引号、注释或截断输入。对极大或深嵌套 JSON,考虑流式解析器或深度限制以防拒绝服务。

json
// Always wrap JSON.parse in try/catch for untrusted input.
function safeParse(str) {
  try {
    return { ok: true, value: JSON.parse(str) };
  } catch (e) {
    return { ok: false, error: e.message };
  }
}

// Common errors:
//   SyntaxError: Unexpected token
//   SyntaxError: Unexpected end of JSON input
//   (no undefined/NaN/Infinity accepted)

// For deeply nested untrusted JSON, limit depth to avoid DoS.
// Consider a streaming parser for very large files.
13

Python 中的解析

json.loads

json.loads 将 JSON 字符串解析为 Python 对象。JSON 对象变 dict,数组变 list,字符串变 str,数字自动变 int 或 float,true/false 变 True/False,null 变 None。'loads' 表示 'load string'。

json
import json

json_str = '{"name": "Alice", "age": 30}'
data = json.loads(json_str)

print(data["name"])  # Alice
print(data["age"])   # 30

# loads = "load string"
# Returns Python objects: dict, list, str, int/float, bool, None
# JSON true/false/null  ->  Python True/False/None
# JSON numbers          ->  int or float (auto)

json.dumps

json.dumps 将 Python 对象序列化为 JSON 字符串。用 indent 美化,ensure_ascii=False 保留 Unicode 字符(而非 \uXXXX 转义),sort_keys=True 产生稳定输出。Python True/False/None 映射为 JSON true/false/null。

json
import json

data = {"name": "Alice", "age": 30, "active": True}

# Compact:
json.dumps(data)
# '{"name": "Alice", "age": 30, "active": true}'

# Pretty-printed:
json.dumps(data, indent=2, ensure_ascii=False)
# {
#   "name": "Alice",
#   "age": 30,
#   "active": true
# }

# ensure_ascii=False keeps Unicode characters readable.
# sort_keys=True produces stable output.

解析文件

用 json.load(文件对象)和 json.dump(文件对象)处理文件;json.loads 和 json.dumps 处理字符串。始终用 encoding='utf-8' 打开文件以避免平台默认值。大文件考虑 ijson(流式)或 orjson(更快)以提升性能。

json
import json

# Read from a file:
with open("data.json", "r", encoding="utf-8") as f:
    data = json.load(f)

# Write to a file:
with open("out.json", "w", encoding="utf-8") as f:
    json.dump(data, f, indent=2, ensure_ascii=False)

# load/dump work on file objects; loads/dumps work on strings.
# Always specify encoding="utf-8" for portability.

自定义编码器

继承 json.JSONEncoder 并重写 default() 序列化 JSON 原生不支持的类型(datetime、set、Decimal、自定义类)。返回 JSON 可序列化的表示。解码时写自定义 hook(object_hook)反向转换。

json
import json
from datetime import datetime, date

class CustomEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, (datetime, date)):
            return obj.isoformat()
        if isinstance(obj, set):
            return sorted(obj)
        return super().default(obj)

data = {"now": datetime.now(), "tags": {"a", "b"}}
json.dumps(data, cls=CustomEncoder)
# '{"now": "2024-...", "tags": ["a", "b"]}'

# The default() method is called for objects json can't serialize.

错误处理

json.loads 对非法输入抛出 json.JSONDecodeError,带行/列信息。常见原因:尾随逗号、单引号、注释、NaN/Infinity(默认拒绝)和字符串中控制字符。需要时用 parse_constant 处理 NaN/Infinity/-Infinity。

json
import json

def safe_loads(s):
    try:
        return {"ok": True, "value": json.loads(s)}
    except json.JSONDecodeError as e:
        return {"ok": False, "error": str(e), "line": e.lineno, "col": e.colno}

# json.JSONDecodeError gives line and column of the error.
# Common causes: trailing commas, single quotes, comments,
#   NaN/Infinity (rejected by default), control chars in strings.

# To allow NaN/Infinity (non-standard):
json.loads('{"x": NaN}', parse_constant=lambda x: None)  # or float(x)

处理 Decimal 与 DateTime

默认 json 将所有数字解析为 float,丢失货币等小数精度。传 parse_float=Decimal 保留精度,并用 default hook 将 Decimal 转回(用 str 保留精度,或 float 若可接受损失)。货币用 str 表示最精确。

json
import json
from decimal import Decimal
from datetime import datetime

# Decimal: parse_float keeps precision (default would lose it)
data = json.loads('{"price": 19.99}', parse_float=Decimal)
print(data["price"])        # Decimal('19.99')
print(data["price"] + Decimal("0.01"))  # 20.00 exact

# Serialize Decimal back:
def encode(obj):
    if isinstance(obj, Decimal):
        return float(obj)   # or str(obj) to keep precision
    raise TypeError

json.dumps({"price": Decimal("19.99")}, default=encode)

# parse_float=float is the default; use Decimal for money.
14

Java 中的解析

Jackson 基础

Jackson 是最流行的 Java JSON 库。ObjectMapper.readValue 将 JSON 解析为 POJO;writeValueAsString 序列化。添加 jackson-databind(以及 jackson-core 和 jackson-annotations)依赖。Jackson 快速、成熟,Spring Boot 默认集成。

json
import com.fasterxml.jackson.databind.ObjectMapper;

ObjectMapper mapper = new ObjectMapper();

// Parse JSON to a Java object:
String json = "{\"name\":\"Alice\",\"age\":30}";
User user = mapper.readValue(json, User.class);

// Serialize a Java object:
String out = mapper.writeValueAsString(user);

// Pretty-print:
String pretty = mapper.writerWithDefaultPrettyPrinter()
                      .writeValueAsString(user);

// Jackson is the de facto JSON library for Java.
// Add: com.fasterxml.jackson.core:jackson-databind

Gson 基础

Gson 是 Google 的 JSON 库,基本用途比 Jackson 更简单。Gson.fromJson 解析;toJson 序列化。用 GsonBuilder 设置选项(美化、null 序列化、自定义适配器)。添加 com.google.code.gson:gson 依赖。Gson 在 Android 中常见。

json
import com.google.gson.Gson;

Gson gson = new Gson();

// Parse:
User user = gson.fromJson(json, User.class);

// Serialize:
String out = gson.toJson(user);

// Pretty-print:
Gson pretty = new GsonBuilder().setPrettyPrinting().create();
String s = pretty.toJson(user);

// Gson (by Google) is simpler than Jackson for basic use.
// Add: com.google.code.gson:gson

JsonNode 树模型

Jackson 的 JsonNode 是无 POJO 导航 JSON 的树模型。用 get()(缺失返回 null)或 path()(返回可安全链式调用的 'missing node')。asText/asInt/asBoolean 有带默认值的重载。schema 未知或变化时有用。

json
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(json);

String name = root.get("name").asText();     // "Alice"
int age = root.get("age").asInt();            // 30
JsonNode hobbies = root.get("hobbies");       // array
for (JsonNode h : hobbies) {
    System.out.println(h.asText());
}

// get() returns null for missing keys; path() returns a
// 'missing node' that you can chain safely.
String city = root.path("address").path("city").asText("unknown");

自定义反序列化

自定义 JsonDeserializer 处理非标准 JSON 编码(如 '$19.99' 表示货币)。用 @JsonDeserialize(using = ...) 注解字段,或为类型注册 SimpleModule。用 JsonSerializer 做自定义序列化。这保持 POJO 不含解析逻辑。

json
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.core.*;
import java.io.IOException;

public class MoneyDeserializer extends JsonDeserializer<Double> {
    @Override
    public Double deserialize(JsonParser p, DeserializationContext ctxt)
            throws IOException {
        String s = p.getText();           // e.g. "$19.99"
        return Double.parseDouble(s.replaceAll("[^0-9.]", ""));
    }
}

// Annotate the field:
//   @JsonDeserialize(using = MoneyDeserializer.class)
//   public double price;

// Or register a module for a type.

流式 API

Jackson 流式 API(JsonParser/JsonGenerator)逐令牌读写 JSON,内存恒定——适合巨大文件。你控制解析循环,可用 skipChildren() 跳过子树。与树或 POJO 模型配合处理实际需要的部分。

json
import com.fasterxml.jackson.core.*;

// Jackson streaming: low memory, fast, for huge files.
JsonFactory f = new JsonFactory();
try (JsonParser p = f.createParser(new File("huge.json"))) {
    while (p.nextToken() != JsonToken.END_OBJECT) {
        String field = p.getCurrentName();
        if ("name".equals(field)) {
            p.nextToken();
            System.out.println(p.getText());
        }
        // skip complex values you don't need:
        // p.skipChildren();
    }
}

// Use streaming for files that won't fit in memory.
15

PHP 中的解析

json_encode

json_encode 将 PHP 值序列化为 JSON。PHP 关联数组变 JSON 对象,顺序数组变 JSON 数组。常见标志:JSON_PRETTY_PRINT、JSON_UNESCAPED_UNICODE(保留可读 Unicode)、JSON_UNESCAPED_SLASHES(不转义 /)。用 | 组合标志。

json
<?php
$data = ["name" => "Alice", "age" => 30, "active" => true];

// Compact (default):
$json = json_encode($data);
// {"name":"Alice","age":30,"active":true}

// Pretty-print:
$pretty = json_encode($data, JSON_PRETTY_PRINT);

// Keep Unicode readable (don't escape to \uXXXX):
$unicode = json_encode($data, JSON_UNESCAPED_UNICODE);

// Combine flags with |:
json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE
           | JSON_UNESCAPED_SLASHES);

json_decode

json_decode 将 JSON 解析为 PHP。第二个参数控制结果:true 返回关联数组,false(默认)返回 stdClass 对象。按访问风格选择($arr['key'] vs $obj->key)。非顺序键的 PHP 数组变 JSON 对象。

json
<?php
$json = '{"name":"Alice","age":30,"hobbies":["reading"]}';

// Default: returns associative array OR object (stdClass)
$data = json_decode($json);
echo $data->name;            // Alice

// Force associative array:
$arr = json_decode($json, true);
echo $arr["name"];           // Alice

// The second argument (assoc) controls array vs object.
// PHP objects become stdClass instances by default.

错误处理

PHP 的 json_decode 默认不抛出——解析后检查 json_last_error() 和 json_last_error_msg()。传 JSON_THROW_ON_ERROR(PHP 7.3+)改为抛出 JsonException,更清晰。常见错误:尾随逗号、单引号和无效 UTF-8。

json
<?php
$json = '{invalid json}';
$data = json_decode($json);

if (json_last_error() !== JSON_ERROR_NONE) {
    echo "Parse error: " . json_last_error_msg();
    // e.g., "Syntax error"
}

// PHP does not throw on JSON errors; check json_last_error().
// Common errors: trailing comma, single quotes, invalid UTF-8.

// To throw exceptions instead:
try {
    $data = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
    echo $e->getMessage();
}

美化输出与标志

常见 json_encode 标志:JSON_PRETTY_PRINT(缩进)、JSON_UNESCAPED_UNICODE(保留可读非 ASCII)、JSON_UNESCAPED_SLASHES(不转义 /)、JSON_NUMERIC_CHECK(数字字符串转数字)、JSON_THROW_ON_ERROR(失败抛出)。用 | 组合。

json
<?php
$data = ["path" => "C:\\Users", "url" => "https://x.com/"];

// Default escapes / and non-ASCII:
json_encode($data);
// {"path":"C:\\Users","url":"https:\/\/x.com\/"}

// Cleaner output:
json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE
           | JSON_PRETTY_PRINT);
// {
//     "path": "C:\\Users",
//     "url": "https://x.com/"
// }

// JSON_NUMERIC_CHECK converts numeric strings to numbers:
json_encode(["id" => "42"], JSON_NUMERIC_CHECK);  // {"id":42}

自定义序列化

实现 JsonSerializable 并定义 jsonSerialize() 控制对象如何编码。这是脱敏字段(如省略 password)、重命名键或在序列化期间计算派生值的最干净方式。方法返回任何 JSON 可序列化结构。

json
<?php
class User implements JsonSerializable {
    public $name;
    public $password;

    public function __construct($name, $password) {
        $this->name = $name;
        $this->password = $password;
    }

    public function jsonSerialize(): mixed {
        return [
            "name" => $this->name,
            // omit password for security
        ];
    }
}

echo json_encode(new User("Alice", "secret"));
// {"name":"Alice"}

// JsonSerializable lets the class control its JSON form.
16

JSON:API 规范

文档结构

JSON:API 是构建一致 JSON API 的规范。文档有顶层 'jsonapi' 版本对象、主 'data' 资源、可选 'included' 相关资源、'meta'(非标准信息)、'links'(分页)和 'errors'(失败)。媒体类型为 application/vnd.api+json。

json
{
  "jsonapi": { "version": "1.1" },
  "data": {
    "type": "articles",
    "id": "1",
    "attributes": {
      "title": "JSON:API Basics"
    },
    "relationships": {
      "author": { "data": { "type": "people", "id": "9" } }
    }
  },
  "included": [
    { "type": "people", "id": "9", "attributes": { "name": "Jane" } }
  ]
}

// JSON:API is a convention for building JSON APIs.
// Top-level keys: jsonapi, data, errors, meta, links, included.

资源对象

JSON:API 资源对象有 'type'(资源种类)和 'id'(字符串标识符),外加 'attributes'(数据)和可选 'relationships'(到其他资源的链接)及 'links'(如 self 的 URL)。ID 必须为字符串。type 和 id 不得出现在 attributes 中。

json
{
  "data": {
    "type": "articles",
    "id": "1",
    "attributes": {
      "title": "Hello",
      "published": true,
      "views": 42
    },
    "links": {
      "self": "/articles/1"
    }
  }
}

// Every resource has a 'type' (string) and 'id' (string).
// 'attributes' holds data; 'relationships' holds links to others.
// 'id' and 'type' MUST NOT appear inside attributes.

关系

关系通过资源标识符对象({type, id})链接到其他资源。to-one 关系用单个标识符;to-many 用数组。'links' 对象提供 'self'(关系 URL)和 'related'(相关资源 URL)用于导航。

json
{
  "data": {
    "type": "articles",
    "id": "1",
    "relationships": {
      "author": {
        "data": { "type": "people", "id": "9" },
        "links": {
          "self": "/articles/1/relationships/author",
          "related": "/articles/1/author"
        }
      },
      "tags": {
        "data": [
          { "type": "tags", "id": "1" },
          { "type": "tags", "id": "2" }
        ]
      }
    }
  }
}

// to-one: data is a single resource identifier.
// to-many: data is an array of resource identifiers.

Meta 与 Links

'meta' 携带非标准信息如总数、速率限制或警告。'links' 提供超媒体导航:self、first、prev、next、last 用于分页,加相关 URL。缺失链接用 null(如首页的 prev)。

json
{
  "meta": {
    "totalPages": 5,
    "currentPage": 1,
    "rateLimit": 100
  },
  "links": {
    "self": "/articles?page=1",
    "first": "/articles?page=1",
    "prev": null,
    "next": "/articles?page=2",
    "last": "/articles?page=5"
  },
  "data": [ /* ... */ ]
}

// meta: non-standard metadata (counts, rate limits, etc.).
// links: pagination and resource URLs.

错误

JSON:API 错误文档有顶层 'errors' 数组(且无 'data')。每个错误对象有可选字段:id、status(HTTP 代码字符串)、code(应用专用)、title(简短摘要)、detail(人类可读解释)、source(通过 JSON Pointer 指向坏字段)和 meta。

json
{
  "errors": [
    {
      "id": "err-123",
      "status": "404",
      "code": "NOT_FOUND",
      "title": "Resource Not Found",
      "detail": "Article 99 does not exist.",
      "source": { "pointer": "/data/attributes/id" },
      "meta": { "requestId": "abc-9" }
    }
  ]
}

// Errors is an array of error objects.
// status: HTTP status string; code: app-specific code.
// source.pointer: JSON Pointer to the offending field.
17

JSON5

JSON5 特性

JSON5 是 JSON 的超集,为人写的配置设计。增加注释、不加引号/单引号字符串、尾随逗号、十六进制/Infinity/NaN 数字和宽松数字格式。JSON5 非标准 JSON——用 JSON5 解析器(json5 npm 包)并转换为 JSON 用于交换。

json
// JSON5 is a superset of JSON with friendlier syntax.
{
  // line comments
  /* block comments */
  unquotedKey: "ok",            // unquoted keys
  "with space": "ok",            // quoted keys still allowed
  singleQuote: 'single',        // single-quoted strings
  trailing: [1, 2, 3,],         // trailing commas
  hex: 0x1F,                     // hexadecimal numbers
  inf: Infinity,                 // Infinity, -Infinity, NaN
  leadingDot: .5,                // leading decimal point
  trailingDot: 5.,               // trailing decimal point
  plus: +5,                      // leading plus
}

// JSON5 is NOT standard JSON—use a JSON5 parser.

注释

JSON5 支持 // 行注释和 /* */ 块注释,标准 JSON 都禁止。这使 JSON5 非常适合人写的配置文件。VS Code 的 settings.json 和 TypeScript 的 tsconfig.json 使用 JSONC(带注释的 JSON),类似但略有不同的子集。

json
{
  // Single-line comment (like JS)
  "name": "Alice",

  /* Block comment
     spanning multiple lines */
  "age": 30,

  "active": true // end-of-line comment
}

// Standard JSON rejects comments.
// JSON5 supports // and /* */ comments everywhere.
// VS Code's settings.json and tsconfig.json use JSONC (a subset).

尾随逗号

JSON5 允许对象和数组最后一个元素后有尾随逗号。标准 JSON 拒绝。尾随逗号减少添加或重排字段时的 diff 噪声(每行都可带逗号)。许多现代语言和配置格式现已允许此。

json
{
  "a": 1,
  "b": 2,
  "c": 3,           // <-- trailing comma OK in JSON5
}

// Arrays too:
[1, 2, 3,]

// Standard JSON rejects trailing commas.
// JSON5 allows them, reducing diff noise when adding fields.

不加引号与单引号字符串

JSON5 允许不加引号的标识符键(匹配 [A-Za-z_$][A-Za-z0-9_$]*)以及单引号和双引号字符串。单引号字符串内转义 ' 为 \';双引号内转义 " 为 \"。这镜像 JavaScript 对象字面量语法以提升可读性。

json
{
  unquoted: "value",          // unquoted identifier key
  "quoted key": "value",       // quoted key (for special chars)
  single: 'single-quoted',     // single-quoted string value
  mixed: 'it\'s ok',           // escape single quote inside
  double: "she said \"hi\"",  // escape double quote inside
}

// Unquoted keys must be valid identifiers ([A-Za-z_$][A-Za-z0-9_$]*).
// Single and double quotes are both allowed for strings.

数字与字符串(扩展)

JSON5 扩展数字:十六进制(0xFF)、前导/尾随小数点(.5、5.)、前导加(+5),以及关键字 Infinity、-Infinity、NaN。这些都被标准 JSON 拒绝。JSON5 字符串仍用转义序列(\n)表示换行——没有裸多行字符串。

json
{
  hex: 0xFF,                    // hexadecimal
  leadingDot: .5,               // .5 instead of 0.5
  trailingDot: 5.,              // 5. instead of 5.0
  leadingPlus: +5,              // +5 (standard JSON rejects +)
  infinity: Infinity,           // Infinity (not in standard JSON)
  negativeInfinity: -Infinity,
  nan: NaN,
  multiline: 'line1\nline2'    // escape sequences like JSON
}

// JSON5 does NOT support real multi-line strings or bareword NaN.
18

JSON Lines (JSONL)

JSONL 格式

JSON Lines(JSONL 或 NDJSON)是每行一个独立完整 JSON 值的格式。无包裹数组。这使其非常适合流式处理、日志和大数据集:可逐行处理而无需加载整个文件。扩展名:.jsonl、.ndjson。

json
// A JSON Lines file (.jsonl / .ndjson) is one JSON value per line:

{"name": "Alice", "age": 30}
{"name": "Bob", "age": 25}
{"name": "Carol", "age": 35}

// Rules:
//   - Each line is a COMPLETE, valid JSON value.
//   - Lines are separated by newlines (\n).
//   - No enclosing [ ] array.
//   - Each line is parsed independently.

读取 JSONL

读取 JSONL 时逐行迭代,用 JSON.parse/loads 解析每行。这以恒定内存流式处理文件——适合巨大数据集。跳过空行。Node.js 中对文件流用 readline;Python 中直接迭代文件对象。无需加载整个文件。

json
// JavaScript (Node.js) — line by line:
const fs = require("fs");
const readline = require("readline");

const rl = readline.createInterface({
  input: fs.createReadStream("data.jsonl"),
  crlfDelay: Infinity,
});

for await (const line of rl) {
  if (!line.trim()) continue;
  const obj = JSON.parse(line);
  console.log(obj.name);
}

// Python:
//   import json
//   with open("data.jsonl") as f:
//       for line in f:
//           obj = json.loads(line)

写入 JSONL

写入 JSONL 时用 JSON.stringify/dumps(紧凑、无缩进)序列化每条记录并追加换行。用可写流(Node)或以写模式打开文件(Python)以提效。紧凑形式保持行短且可解析;每行一条记录是规则。

json
// JavaScript (Node.js):
const fs = require("fs");
const out = fs.createWriteStream("out.jsonl");
for (const obj of records) {
  out.write(JSON.stringify(obj) + "\n");
}
out.end();

// Python:
//   import json
//   with open("out.jsonl", "w") as f:
//       for obj in records:
//           f.write(json.dumps(obj) + "\n")

// One JSON per line; compact form (no indent) is conventional.

使用场景

JSONL 适用于日志文件、大数据集、ML 训练数据、数据库转储和仅追加事件流。每行独立,故可追加而无需重写、在损坏行后恢复解析、并行处理。jq 和 shell 管道等工具自然配合它。

json
// JSONL is ideal for:
//   - log files (one event per line)
//   - large datasets (streaming, append-only)
//   - machine learning training data
//   - database exports/imports
//   - append-only event streams

// Example: log entry per line
{"ts": "2024-01-15T10:00:00Z", "level": "info", "msg": "started"}
{"ts": "2024-01-15T10:00:01Z", "level": "error", "msg": "failed"}

// Tools: jq, xargs, awk | json.loads — all work line-by-line.

JSONL 与 JSON 数组对比

JSON 数组用 [ ] 包裹记录,需加载(或小心流式)整个文件才能解析。JSONL 每行一条记录,实现真正流式、易追加和从损坏行恢复。对大型或不断增长的数据集,JSONL 几乎总是更好选择。

json
// JSON Array (one big file):
[
  {"name": "Alice"},
  {"name": "Bob"},
  {"name": "Carol"}
]

// JSONL (one per line):
{"name": "Alice"}
{"name": "Bob"}
{"name": "Carol"}

// JSON Array: must load whole file to parse; hard to append.
// JSONL: streamable, appendable, resumable; slightly more
//        per-record overhead but far better for big files.
19

安全

JSONP 风险

JSONP 将 JSON 包裹在 JavaScript 回调中,使 <script> 标签可获取跨域数据,绕过同源策略。这很危险:任何站点都可读取响应,回调注入可致 XSS,请求携带受害者 cookie。改用 CORS——JSONP 是遗留且不安全的。

json
// JSONP (JSON with Padding) bypasses same-origin policy
// by wrapping JSON in a script callback:
callbackHandler({"secret": "data"});

// Loaded via <script src="https://api.example.com/data?callback=callbackHandler">

// RISKS:
//   - Any site can include the URL and read the response.
//   - XSS if the callback name is attacker-controlled.
//   - CSRF: the request is made with the victim's cookies.

// MODERN ALTERNATIVE: use CORS instead of JSONP.
// JSONP is legacy—avoid it for new APIs.

XSS 防护

嵌入 HTML <script> 标签的 JSON 可致 XSS:字符串 '</script>' 会提前结束脚本。另外 U+2028 和 U+2029(行/段落分隔符)在 JSON 字符串中合法但会破坏 JavaScript。嵌入 JSON 到 HTML 时转义 <、>、&、U+2028、U+2029,或用 serialize-javascript 等库。

json
// JSON itself is data, not executable—BUT embedding it in
// HTML can cause XSS if not careful.

// BAD: output JSON inside <script> without escaping:
//   <script>
//     var data = {"name": "</script><script>alert(1)</script>"};
//   </script>

// GOOD: escape < and > (and &) when embedding in HTML:
const safe = JSON.stringify(data)
  .replace(/</g, "\\u003c")
  .replace(/>/g, "\\u003e")
  .replace(/&/g, "\\u0026")
  .replace(/\u2028/g, "\\u2028")
  .replace(/\u2029/g, "\\u2029");

// Or use a library: js-xss, serialize-javascript.

原型污染

将不可信 JSON 合并到对象时可能污染原型:含 '__proto__' 或 'constructor' 键的不可信 JSON 会毒化 Object.prototype,影响所有对象。防御:用 Object.create(null)、阻止危险键、对不可信数据优先用 Map、保持合并库更新。

json
// Merging untrusted JSON into objects can pollute prototypes:
const evil = JSON.parse('{"__proto__": {"isAdmin": true}}');

// BAD merge (Object.assign does NOT pollute, but some libs do):
//   function merge(target, src) {
//     for (const k in src) target[k] = src[k];
//   }

// Attackers can set Object.prototype.isAdmin = true,
// affecting ALL objects.

// Defenses:
//   - Use Object.create(null) for parsed objects.
//   - Block keys like __proto__, constructor, prototype.
//   - Use Map instead of plain objects for untrusted data.
//   - Keep dependencies updated (some had merge() flaws).

通过 JSON 注入

JSON 本身抗注入,但用字符串拼接构建很危险——用户输入可破坏 JSON 结构。始终用真正的序列化器(JSON.stringify)。下游同理:用参数化 SQL 查询、带参数数组的 execFile 和 HTML 转义的模板引擎。

json
// JSON itself is not injectable, but building JSON by
// concatenation is dangerous:

// BAD: string concatenation
//   const json = '{"name": "' + userInput + '"}';
//   // userInput = '"); drop table; //'  ->  breaks out

// GOOD: always use a real serializer
const json = JSON.stringify({ name: userInput });

// For SQL: use parameterized queries, not JSON interpolation.
// For shell: use execFile with arg arrays, not string concat.
// For HTML: use textContent or a templating engine that escapes.

通过大型或深层 JSON 的 DoS

基于 JSON 的 DoS:巨大文件耗尽内存、深嵌套溢出解析器栈、病态结构('billion laughs' 的 JSON 类比)膨胀小输入。防御:在代理层限制请求体大小、限制解析深度、对大输入用流式解析器、设置超时。

json
// Attackers can craft JSON to exhaust memory or CPU:
//
//   1. Huge file: 1 GB of '[1,1,1,...]' to exhaust RAM.
//   2. Deep nesting: '{"a":{"a":{"a":...}}}' (10000 levels)
//      to overflow the parser's stack.
//   3. 'Billion laughs': nested entity expansion (XML-era,
//      but JSON analogs exist with $ref in some libs).
//   4. Many keys: 10 million keys in one object.

// Defenses:
//   - Cap request body size at the server/reverse proxy.
//   - Limit parsing depth (Ajv, fast-json-parse options).
//   - Use streaming parsers (stream-json, oboe) for big input.
//   - Set timeouts on parsing.

安全解析实践

安全 JSON 解析:始终用 JSON.parse(绝不用 eval),使用前对照 schema(Ajv、jsonschema)验证,限制深度和键数,禁用 __proto__ 键,考虑在 Web Worker 或沙箱中解析不可信输入。JSON.parse 本身对代码执行安全;风险在于如何使用解析后的数据。

json
// 1. Validate with a schema before using untrusted JSON.
const Ajv = require("ajv");
const ajv = new Ajv({ allErrors: true });
const validate = ajv.compile(schema);
if (!validate(data)) throw new Error(ajv.errorsText(validate.errors));

// 2. Limit depth and key count when parsing.
// 3. Use reviver/replacer to coerce types safely.
// 4. Never eval() or Function('return ' + json) — use JSON.parse.
// 5. Disable dangerous features (e.g., __proto__ keys).
// 6. Parse untrusted JSON in a sandbox or worker if possible.

// JSON.parse is safe; eval is NOT.
20

最佳实践与工具

Schema 优先

schema 优先设计 API:定义 JSON Schema,从中生成语言类型(typescript-json-schema、quicktype、jsonschema2pojo),并在运行时验证请求/响应。这能及早捕获契约违规、启用代码生成并充当活文档。

json
// Define a JSON Schema before shipping an API.
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["id", "name"],
  "properties": {
    "id":   { "type": "integer" },
    "name": { "type": "string", "minLength": 1, "maxLength": 100 }
  },
  "additionalProperties": false
}

// Generate types from the schema (TypeScript, Java, Go, ...).
// Validate both requests and responses against the schema.
// Publish the schema for clients (OpenAPI, JSON Schema).

一致命名

为键选择一种命名约定并一致应用:camelCase(大多数 JSON API 和 JS)、snake_case(Python/Ruby 后端、Google API)或 PascalCase(.NET)。混用风格令人困惑。前后端不同时,在单一边界转换,而非在 schema 中混用。

json
// Pick ONE naming convention and apply it everywhere.

// camelCase (most JSON APIs, JavaScript ecosystem):
{ "firstName": "Alice", "lastName": "Smith" }

// snake_case (Python/Ruby backends, many Google APIs):
{ "first_name": "Alice", "last_name": "Smith" }

// kebab-case (rare in JSON, common in URLs/config):
{ "first-name": "Alice" }

// PascalCase (rare in JSON keys, common in C#/.NET types):
{ "FirstName": "Alice" }

// Avoid mixing; convert at the boundary if the front/back differ.

版本控制

从第一天起版本化 API:URL 路径(/v1/)、载荷中的版本字段、Accept 头(媒体类型)或命名空间(JSON-LD @context)。新增可选字段通常非破坏性;对移除/重命名字段或改变语义的破坏性变更,提升版本号。

json
// 1. Version in the URL path:
//    https://api.example.com/v1/users

// 2. Version field in the payload:
{ "version": "1.0", "data": { ... } }

// 3. Accept header / media type:
//    Accept: application/vnd.example.v1+json

// 4. Namespace the JSON (JSON-LD, JSON:API 'type'):
{ "@context": "https://schema.org/v1", ... }

// Plan for evolution: add optional fields freely, but bump
// the version for breaking changes (removed/renamed fields,
// changed semantics or types).

编码(UTF-8)

UTF-8 是 JSON 的默认且唯一广泛推荐编码。文件保存为 UTF-8 不带 BOM(部分解析器处理不当),设置带 charset=utf-8 的 Content-Type,Content-Length 用字节。Python 中传 ensure_ascii=False 保留 Unicode 可读而非 \uXXXX 转义。

json
// Always use UTF-8 for JSON.
//   - Save files as UTF-8 (no BOM).
//   - Set Content-Type: application/json; charset=utf-8.
//   - Set Content-Length in bytes (not characters).

// In Node.js:
res.setHeader("Content-Type", "application/json; charset=utf-8");
res.end(JSON.stringify(data));

// In Python:
import json
with open("out.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False)

// ensure_ascii=False keeps Unicode readable in the file.

性能技巧

性能:用流式解析(ijson、stream-json、Jackson streaming)而非缓冲处理大 JSON;用快速序列化器(orjson、fast-json-stringify);传输用紧凑形式并通过 HTTP 用 gzip/brotli 压缩;避免深嵌套和巨大数组;缓存解析结果避免重复解析。

json
// 1. Stream large JSON instead of buffering it all.
//    - Node: stream-json, JSONStream
//    - Python: ijson
//    - Java: Jackson streaming API

// 2. Use a fast serializer:
//    - Node: fast-json-stringify (schema-based), orjson (Python)
//    - Compile serializers from a schema for hot paths.

// 3. Compact JSON for transmission; pretty only for humans.

// 4. Avoid deep nesting and huge arrays when possible.

// 5. Compress with gzip/brotli over HTTP (huge savings).

// 6. Cache parsed results; don't re-parse the same payload.

工具与验证器

处理 JSON 的工具:在线验证器(jsonlint.com、jsonschemavalidator.net)、CLI 工具(jq 用于查询/格式化、jsonschema 用于验证)、编辑器支持(VS Code 和 JetBrains 内置 JSON + schema 验证)和代码生成器(quicktype 从 JSON 或 schema 生成 TypeScript/Java/Go 等类型)。

json
// Online validators:
//   - https://jsonlint.com
//   - https://jsonformatter.org
//   - https://www.jsonschemavalidator.net

// CLI tools:
//   - jq          (filter, query, format JSON on the command line)
//   - jaq         (Rust jq clone, faster)
//   - jsonschema  (Python CLI for schema validation)
//   - ajv         (Node CLI/library for JSON Schema)

// Editor support:
//   - VS Code: built-in JSON + schema validation
//   - JetBrains: built-in JSON + schema support
//   - vim/emacs: plugins available

// Schema tools:
//   - quicktype   (generate types from JSON)
//   - typescript-json-schema
//   - jsonschema2pojo (Java)

这篇内容对您有帮助吗?

学习路径

从零开始学习

通过结构化课程从头学习这个语言。