简介:JSON完整示例工程,面向Java初学者与Web开发者,用于快速掌握JSON数据格式的语法规则、解析与生成方法。压缩包内共22个文件,包含2个Java源文件及对应class文件、14个jar依赖库(json-lib、commons-beanutils、junit等),并附带项目配置文件和json笔记,可直接作为Eclipse工程导入运行。资源大小仅2.88MB,结构清晰,适合边看边练。工程示例覆盖字符串、数字、数组、嵌套对象等数据类型,帮助读者理解JSON键值对组织方式,并演示在Java环境中如何调用类库完成对象与JSON字符串的互转;笔记部分进一步梳理了双引号键名、逗号规则等易错点。目前已有3576人学习下载,对正在学习Ajax、接口调试或前后端数据交互的开发者颇有参考价值。 聊到 JSON,很多人搜"json完整例子"其实是想找一个能直接抄、能看懂、能套到自己项目里的现成模板。搜索记录里那些 json 格式、json 数组、json 转换、json 文件用什么打开,还有各种 [object Object]、missing field 报错,说明你不是一个人。这篇文章我打算把 JSON 的学习、使用、踩坑、排查串成一条线,用一份完整的书架配置 JSON 做主线,从 6 种数据类型讲到跨语言解析,再从高频报错讲到 JSON Schema 校验和数据库存储。适合刚接触 JSON 的新手照着敲,也适合被前后端联调折磨的朋友拿来当速查手册。
1. 一个完整 JSON 例子:先看长什么样,再理解为什么
1.1 可直接复制的 JSON 完整示例
我给你一份我自己经常用来演示的"书架配置" JSON。它不算复杂,但覆盖了工作中最常见的 90% 场景:字符串、数字、布尔、null、数组、嵌套对象,一个不少。
{ "project": "我的书架", "version": 2026, "enabled": true, "styles": null, "categories": [ { "id": 1, "name": "编程", "tags": ["json", "python", "java"], "popular": true }, { "id": 2, "name": "工具", "tags": ["sqlite", "c++"], "popular": false } ], "preferences": { "theme": "dark", "fontSize": 14, "showNumbers": true } }把这段内容保存成shelf.json,用 VS Code 或任意文本编辑器打开,你就能得到一个结构清晰、能被绝大多数系统直接解析的完整例子。实际项目里那些影视配置、书源配置、地图边界配置,本质上都是这一类 JSON:最外层一个对象,内部用数组和对象做层级嵌套,最后被不同的解析器读走。
1.2 JSON 的 6 种数据类型与语法红线
JSON 只有 6 种数据类型,记住这张表就够了:
| 类型 | 示例 | 说明 |
|---|---|---|
| 字符串 | "json" | 必须双引号,不能用单引号 |
| 数字 | 2026,14.5 | 整数小数均可,不能有前缀 0 |
| 布尔 | true/false | 只有小写 |
| null | null | 表示空值,不能写成 None、nil |
| 数组 | ["json", "python"] | 有序列表,用中括号 |
| 对象 | {"id": 1} | 键值对集合,用大括号 |
我刚接触 JSON 时踩过最大的坑有两个。一是键必须用双引号,JavaScript 对象里那种{ name: '王' }写法在 JSON 里直接判错;二是最后一个元素后面不能有逗号,很多人写多行数据时习惯性在末尾加逗号,解析器会毫不留情地报错。
JSON 全称是 JavaScript Object Notation,但它已经超越语言本身,成了各语言通用的数据交换格式。它不能写注释,不能有函数,不能有 undefined。如果你需要给配置加说明,应该放在description字段里,而不是靠注释。
1.3 打开和格式化 JSON:浏览器、编辑器,一个都不省心
"json 用什么打开"这个问题,看起来简单,其实有讲究。
- 记事本能打开但全是黑压压一行,不推荐。
- VS Code 打开后按
Shift + Alt + F可以一键格式化,推荐日常使用。 - Chrome / Edge 直接打开
.json文件,有时能显示,但如果是本地file://协议,浏览器会出于安全限制禁止页面通过 fetch 读取同目录下的其他 JSON 文件。
很多人在 Edge 里双击本地 JSON,发现页面空白或者报跨域错误,不是文件坏了,是浏览器策略。正确做法是用 VS Code 的 Live Server 插件起一个本地服务,再用http://localhost:5500访问,这样页面的 fetch 请求才能正常读到 JSON。
提示:JSON 文件请统一保存为 UTF-8 编码,带不带 BOM 都可能造成解析器报错。VS Code 右下角能看到当前文件编码,改成 UTF-8 再保存。
2. 实操中怎么用 JSON:转换、顺序、解析
2.1 字符串转 JSON 的三种语言正确姿势
JSON 在真实业务里最常见的操作就是"字符串 ↔ 对象"互相转换。不同语言写法不同,但思路一致。
Python 使用内置模块json:
import json data = '{"project": "我的书架", "enabled": true}' obj = json.loads(data) # 字符串 -> 字典 print(obj["project"]) back = json.dumps(obj, ensure_ascii=False, indent=2) print(back) # 字典 -> 字符串ensure_ascii=False这行是关键。不加的话,中文会被转成\u6211\u7684...这类 Unicode 转义,虽然程序能读,但人没法看。加上的好处是字符串里直接保留中文。
Java 里我常用 Jackson:
ObjectMapper mapper = new ObjectMapper(); Map<String, Object> obj = mapper.readValue(data, Map.class); String json = mapper.writeValueAsString(obj);注意,如果直接序列化自定义 Java Bean,字段名可能和预期不一致,这个在第 3 节会说。
JavaScript 就是前端老熟人了:
const obj = JSON.parse(data); const str = JSON.stringify(obj, null, 2);JSON.stringify的第三个参数2表示缩进 2 个空格,调试时非常好用。
提示:任何语言的 JSON 解析都可能失败,解析代码一定要放进 try/catch 里。尤其在前端,不要假设接口返回的一定是合法 JSON。
2.2 对象转 JSON 怎么保持顺序
很多人问"对象转 JSON 保持顺序",因为接口对接时字段顺序有时是签名校验的一部分。Java 里如果直接序列化HashMap,顺序不保证;改用LinkedHashMap可以按插入顺序输出。
更保险的做法是用 Jackson 的注解:
@JsonPropertyOrder({"project", "version", "enabled"}) public class Config { private String project; private int version; private boolean enabled; }Python 3.7 之后字典天然保持插入顺序,直接json.dumps输出的就是写入顺序。JavaScript 中普通对象的字符串键也会按插入顺序输出,但数字键会自动按升序排在最前面,比如{"3": "a", "1": "b"}会被序列化成{"1":"b","3":"a"}。如果对顺序有硬要求,建议用Map或数组。
2.3 从 labelme 到地图到试卷:JSON 解析的落地场景
JSON 解析不只是后端接口的事,很多工具链也靠它。
Labelme 标注工具导出的多边形标注就是 JSON 文件,里面是每个点的坐标数组。要把多边形 JSON 转成 YOLO 格式的 txt,核心逻辑就是读取shapes数组,把每个多边形的points归一化成目标格式。
地图场景同理。天地图、高德这类平台提供的边界数据经常是 GeoJSON,本质上是一个包含geometry和coordinates的大型 JSON。你可以自己写脚本把 GeoJSON 转成 SVG 路径,也可以丢给现成工具处理。
试卷上传解析成结构化 JSON 也是同一套玩法:上传 PDF 或图片,OCR 识别后按题型、题干、选项、答案组织成 JSON,后续存入数据库或者渲染成页面都方便。
这些例子说明一件事:JSON 是一种"中间语言",它的价值不在文件本身,而在于不同系统之间能用它对话。你只要掌握了解析和遍历,剩下就是业务逻辑问题。
3. JSON 高频报错与排查技巧实录
3.1 failed to deserialize: missing field
这条报错在 Rust 的 serde 里最典型,完整提示一般是failed to deserialize the JSON body into the target type: input: missing field。原因就一个:JSON 里的字段和服务端结构体里的字段对不上。
排查顺序是:
- 检查 JSON 字段名和代码字段名是否一致,大小写、下划线都可能出问题。
- 检查可选字段是否声明成默认值,比如 Rust 里要加
#[serde(default)]。 - 检查是不是 null 被当成缺失。JSON 里
"field": null和没有这个字段,语义不同,很多严格反序列化框架会区分。
我曾经因为 Java 后端返回createTime,前端传的是create_time,导致联调半小时。最好的解决办法是统一定义字段命名策略,或者只允许一种命名方式。
3.2 Uncaught (in promise) SyntaxError: "[object Object]" is not valid JSON
前端最常见的报错之一。出现这个,说明你调用了JSON.parse(something),但 something 不是 JSON 字符串,而是对象被强制转成了字符串,结果就是"[object Object]"。
典型场景:
// 错误 const res = await fetch('/api/config'); const data = JSON.parse(res); // res 是 Response 对象 // 正确 const data = await res.json();另一个常见场景是后端返回的不是 JSON,而是普通文本或 HTML 错误页。你用res.json()解析时也会报错。正确做法是先打印原始文本:
const text = await res.text(); console.log(text);看一眼实际返回的是什么,再决定用JSON.parse(text)还是走错误处理分支。
3.3 Java Bean 大写字母开头的变量序列化后变小写
这个坑非常经典。Java 里如果字段名是大写字母开头,比如:
private String SName;很多 JSON 库会把它序列化成sname或SName,表现不一。原因在于 JavaBeans 规范规定属性名由getter推导,getSName()被解析成属性SName还是sname取决于具体实现。
解决办法是显式指定 JSON 字段名:
@JsonProperty("SName") private String SName;不要依赖框架的"智能推断",特别是当字段名是 UUID、IP 这类缩写开头时,加注解最稳。
3.4 编辑器看着没问题,解析却报错
很多时候我们把 JSON 从网页或 PDF 里复制出来,看起来没问题,一校验就挂。常见原因有:
- 全角引号。复制中文内容时,双引号变成中文引号
“”,JSON 要求必须是 ASCII 引号"。 - 隐藏不可见字符。比如零宽空格。
- 多了 BOM。用在线校验工具一眼就能看出来。
提示:别用记事本手写大 JSON,我见过太多因为不可见字符折腾一上午的案例。要用就用 VS Code 这类能显示空白字符的编辑器。
3.5 中文乱码和 JSON 文件打不开
中文乱码基本都是编码问题。保存文件时用 UTF-8,读取时也按 UTF-8,就不会乱。如果别人发你的文件打开是乱码,可能是对方用了 GBK,先用 VS Code 重新打开并选择编码,或者用 Python 转一下:
with open('shelf.json', 'r', encoding='utf-8') as f: data = json.load(f)大 JSON 文件卡顿的话,别用记事本硬开。用 VS Code 的jq命令行工具切片处理。jq '.categories[0]' shelf.json可以只输出第一个分类,速度快,内存占用低。
4. 让 JSON 更稳定:Schema 校验、存储、工具清单
4.1 JSON Schema:给 JSON 立规矩
JSON 本身没有强制结构,这既是优点也是缺点。接口调用方传少了字段,传错类型,后端只能靠运行时判断。JSON Schema 就是给 JSON 写"格式说明",相当于数据库表结构。
比如规定name必须是字符串且不能为空:
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "required": ["name"], "properties": { "name": { "type": "string", "minLength": 1 } } }很多接口框架支持用 JSON Schema 自动生成校验代码,或者靠它生成文档。项目里如果有人传了一个不符合规则的 JSON,你能第一时间告诉他是哪个字段出了错,而不是给对方一个只有一句"解析失败"的报错。
4.2 JSON 存入 SQLite:C++ 的一种可行方案
SQLite 本身没有 JSON 类型,最常见的做法是把整个 JSON 存成 TEXT 字段,在应用层用 JSON 库解析。C++ 里可以用 nlohmann/json 配 sqlite3 实现。
基本思路是:
- 用
json::parse()把 JSON 字符串解析成对象。 - 从对象里取出需要作为独立列的值,比如
id、project。 - 把整个 JSON 序列化回字符串,作为
payload字段插入表里。
示例 SQL:
CREATE TABLE shelf ( id INTEGER PRIMARY KEY, project TEXT, payload TEXT );插入时把完整 JSON 放进payload,查询时再json::parse(payload)拿出来。这样既能对少量核心字段建索引,又保留了完整数据结构,是兼顾灵活性和查询性能的务实方案。
4.3 我的 JSON 工具清单与避坑建议
最后分享一下我日常处理 JSON 的固定组合:
- 编辑:VS Code + Prettier 插件
- 校验:在线 JSON Validator 或者本地
python -m json.tool shelf.json - 查询和过滤:jq 命令行工具
- 生成:能程序生成就别手写,手写大 JSON 必出错
python -m json.tool shelf.json这个命令我用了很多年。写脚本时想快速看看某份 JSON 是否合法,直接对文件执行它,如果有语法错误会直接告诉你第几行的问题,比肉眼找靠谱多了。
我自己用 JSON 这几年最大的体会是:JSON 本身不难,难的是它太"自由"。结构里多个空数组、字段偶尔缺失、类型偶尔从字符串变数字,都会在某个意想不到的深夜给你惊喜。所以我现在做任何对接,第一件事不是写解析代码,而是先确认"这份 JSON 到底有没有固定结构,哪些字段一定存在,哪些是可选"。能用 Schema 约束就约束,不能约束就把所有解析都封装成带默认值的函数。这样哪怕对方哪天改坏了数据结构,你顶多日志里多一条警告,而不是整个服务崩溃。
最后再分享一个小技巧:如果你收到一份陌生的 JSON,先别急着看内容,先格式化,然后一层层折叠对象。从最外层开始,依次展开categories、preferences、tags这些节点,整个数据结构在脑子里就会立刻清晰起来。处理 JSON 这件事,慢就是快,结构看清了,后面写代码都是顺水推舟。
本文还有配套的精品资源,点击获取