JSON 格式化与验证:完整开发者指南
· 12分钟阅读
目录
JSON(JavaScript Object Notation)已成为网络数据交换的事实标准。无论您是构建 REST API、配置应用程序还是存储结构化数据,理解 JSON 格式化和验证对于现代开发都至关重要。
本综合指南涵盖了从基本语法规则到高级验证技术、安全考虑以及跨不同编程语言和环境的实用工具的所有内容。
JSON 语法规则
JSON 是一种轻量级、基于文本的数据交换格式,既易于人类阅读,也易于机器解析。尽管其名称暗示与 JavaScript 有关,但 JSON 完全独立于语言,几乎所有现代编程语言都支持它。
该格式最初由 Douglas Crockford 指定,现在由 RFC 8259 定义。其简单性和通用性使其成为 API、配置文件、NoSQL 数据库和全球数据存储系统的首选。
核心数据类型
JSON 支持恰好六种数据类型,每种都有特定的格式要求:
| 类型 | 示例 | 注释 |
|---|---|---|
| 字符串 | "hello world" |
必须使用双引号,支持 Unicode 转义序列 |
| 数字 | 42、3.14、-1、2.5e10 |
无前导零,无十六进制,支持科学计数法 |
| 布尔值 | true、false |
仅小写,无引号 |
| 空值 | null |
仅小写,表示值的缺失 |
| 对象 | {"key": "value"} |
无序集合,键必须是字符串 |
| 数组 | [1, 2, 3] |
有序列表,可包含混合类型 |
专业提示:使用我们的 JSON 格式化工具 即时验证和美化您的 JSON,带有语法高亮和错误检测。
字符串转义规则
JSON 字符串需要对特殊字符进行适当转义。以下是基本的转义序列:
\"- 双引号\\- 反斜杠\/- 正斜杠(可选但有效)\b- 退格\f- 换页\n- 换行\r- 回车\t- 制表符\uXXXX- Unicode 字符(4位十六进制数字)
带转义字符的示例:
{
"message": "Line 1\nLine 2",
"path": "C:\\Users\\Documents",
"quote": "He said \"Hello\"",
"emoji": "\u2764\uFE0F"
}
数字格式规范
JSON 数字遵循严格的格式规则,与某些编程语言不同:
- 无前导零:
042无效,使用42 - 无十六进制:
0xFF无效 - 无八进制:
0o77无效 - 小数点需要数字:
.5无效,使用0.5 - 允许科学计数法:
1.5e10、2E-5 - 无特殊值:
NaN、Infinity、-Infinity无效
常见 JSON 错误及修复方法
即使是经验丰富的开发者也会犯 JSON 语法错误。了解最常见的错误可以帮助您更快地调试并从一开始就编写有效的 JSON。
| 错误 | 无效示例 | 有效示例 | 说明 |
|---|---|---|---|
| 尾随逗号 | {"a": 1,} |
{"a": 1} |
JSON 不允许对象或数组中的尾随逗号 |
| 单引号 | {'a': 'b'} |
{"a": "b"} |
字符串和键只能使用双引号 |
| 未加引号的键 | {name: "John"} |
{"name": "John"} |
对象键必须始终是带引号的字符串 |
| 注释 | {"a": 1} // comment |
不允许 | JSON 规范不支持注释 |
| 裸值 | hello |
"hello" |
顶级值必须是对象、数组或带引号的字符串 |
| 未定义 | {"a": undefined} |
{"a": null} |
使用 null 而不是 undefined |
| 缺少引号 | {"date": 2024-01-01} |
{"date": "2024-01-01"} |
非数字值需要引号 |
快速提示:使用我们的 JSON 验证器 即时捕获这些错误,并提供详细的错误消息,准确显示问题所在位置。
调试解析错误
当 JSON 解析失败时,错误消息通常指向字符位置。以下是如何解释常见错误消息:
- "Unexpected token"(意外标记) - 通常意味着语法字符位置错误(逗号、括号、引号)
- "Unexpected end of input"(意外的输入结束) - 缺少右括号、大括号或引号
- "Expected property name"(期望属性名) - 缺少或无效的对象键
- "Unexpected string"(意外字符串) - 对象属性或数组元素之间缺少逗号
大多数现代验证器会显示错误发生的确切行和列,使调试比手动检查快得多。
格式化和美化输出
压缩的 JSON 紧凑且高效用于数据传输,但人类几乎无法阅读。美化输出添加空白以使结构清晰且易于浏览。
压缩与美化输出
以下是两种格式的相同数据:
// 压缩(1行,68字节)
{"name":"John","age":30,"city":"New York","skills":["JavaScript","Python"]}
// 2空格缩进的美化输出(6行,108字节)
{
"name": "John",
"age": 30,
"city": "New York",
"skills": ["JavaScript", "Python"]
}
压缩版本节省了40字节(减少37%),但牺牲了所有可读性。对于生产 API,压缩的 JSON 减少带宽并提高性能。对于开发、配置文件和调试,美化输出的 JSON 至关重要。
缩进样式
不同的社区对缩进有不同的偏好:
- 2个空格 - 在 Web 开发、JavaScript 和 JSON API 中最流行
- 4个空格 - 在 Python 项目和企业 Java 应用程序中常见
- 制表符 - 对于 JSON 不太常见,但在某些项目中用于可访问性
关键是在项目内保持一致性。大多数团队通过代码检查工具和编辑器配置来强制执行此操作。
专业提示:配置您的编辑器在保存时格式化 JSON。VS Code 用户可以在设置中添加 "editor.formatOnSave": true 并安装 JSON 格式化扩展。
对象键排序
虽然 JSON 对象在技术上是无序的,但按字母顺序对键进行排序可以提高可读性,并使版本控制中的差异更清晰:
// 未排序
{
"version": "1.0",
"name": "myapp",
"author": "John Doe",
"dependencies": {}
}
// 按字母顺序排序
{
"author": "John Doe",
"dependencies": {},
"name": "myapp",
"version": "1.0"
}
许多 JSON 格式化工具提供自动键排序作为选项。这对于多个开发者频繁编辑的配置文件特别有用。
JSONPath 查询
JSONPath 提供了一种从 JSON 文档中提取数据的查询语言,类似于 XPath 对 XML 的作用。在处理复杂的嵌套结构或需要以编程方式提取特定值时,它非常宝贵。
基本 JSONPath 语法
JSONPath 表达式以 $ 开头,表示根元素,后跟子运算符和过滤器:
| 表达式 | 含义 | 示例结果 |
|---|---|---|
$ |
根元素 | 整个文档 |
$.store.book |
商店中的所有书籍 | 书籍对象数组 |
$.store.book[0] |
第一本书 | 单个书籍对象 |
$.store.book[-1] |
最后一本书 | 单个书籍对象 |
$.store.book[0,2] |
第一本和第三本书 | 包含2本书的数组 |
$.store.book[0:2] |
前两本书(切片) | 包含2本书的数组 |
$.store.book[*].title |
所有书名 | 字符串数组 |
$..price |
所有价格(递归) | 数字数组 |
$.store.book[?(@.price<10)] |
10美元以下的书籍 | 过滤后的数组 |
$.store.book[?(@.category=='fiction')] |
小说类书籍 | 过滤后的数组 |
快速提示:使用我们的 JSONPath 查找器 工具交互式测试您的 JSONPath 查询,实时查看结果。
高级过滤
JSONPath 支持使用比较运算符和逻辑条件的复杂过滤表达式:
==- 等于(在某些实现中使用单个 =)!=- 不等于<、<=、>、>=- 比较运算符&&- 逻辑与||- 逻辑或@- 过滤器中的当前节点
多条件示例:
// 查找小说类且价格低于15美元的书籍
$.store.book[?(@.category=='fiction' && @.price<15)]
// 查找特定作者的书籍
$.store.book[?(@.author=='Tolkien' || @.author=='Rowling')]
// 查找有 ISBN 的书籍
$.store.book[?(@.isbn)]
实际用例
JSONPath 在几个实际场景中表现出色:
- API 响应解析 - 从复杂的 API 响应中提取特定字段,无需手动遍历
- 配置管理 - 在大型配置文件中查询嵌套配置值
- 数据转换 - 为 ETL 管道选择和重塑数据
- 测试和验证 - 在 API 测试套件中断言特定值
- 日志分析 - 从结构化 JSON 日志中提取相关字段
JSON Schema 验证
JSON Schema 是一种词汇表,允许您注释和验证 JSON 文档。它为您的 JSON 数据提供契约,确保其满足特定的结构和类型要求。
为什么使用 JSON Schema?
Schema 验证提供了几个关键优势:
- 数据验证 - 自动验证传入数据是否符合预期结构
- 文档 - Schema 作为机器可读的文档
- 代码生成 - 从 schema 生成类型、类和验证代码
- API 契约 - 定义服务之间的清晰契约
- 错误预防 - 在数据问题导致运行时错误之前捕获它们
基本 Schema 示例
以下是定义用户对象的简单 schema:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 100
},
"email": {
"type": "string",
"format": "email"
},
"age": {
"type": "integer",
"minimum": 0,
"maximum": 150
},
"roles": {
"type": "array",
"items": {
"type": "string",
"enum": ["admin", "user", "guest"]
},
"minItems": 1,
"uniqueItems": true
}
},
"required": ["name", "email"],
"additionalProperties": false
}
此 schema 强制要求有效的用户对象必须具有姓名和电子邮件,以及满足特定约束的可选年龄和角色字段。