JSON格式
Json介绍
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,以其简洁的结构和高效的解析能力广泛应用于各种场景。以下是对JSON格式的详细介绍:
1. 基本结构
JSON由两种基础结构组成:
-
对象(Object):用大括号
{}
包裹,表示键值对集合。键名(字符串)与值之间用冒号:
分隔,键值对之间用逗号,
分隔。{ "name": "李四", "age": 25 }
-
数组(Array):用方括号
[]
包裹,表示值的有序列表,元素间用逗号,
分隔。["苹果", "香蕉", "橘子"]
2. 数据类型
JSON支持以下数据类型:
- 字符串(String):双引号包裹,支持转义字符(如
\"
、\n
)。 - 数字(Number):整数或浮点数(如
42
、3.14
)。 - 布尔值(Boolean):
true
或false
。 - 空值(Null):
null
。 - 对象(Object):嵌套的键值对。
- 数组(Array):嵌套的值列表。
3. 语法规则
- 键名必须为双引号包裹的字符串:单引号或无引号无效。
- 字符串值必须用双引号:例如
"Hello"
有效,'Hello'
无效。 - 逗号与冒号使用严格:最后一个元素后不能有逗号,键值间用冒号分隔。
- 层级嵌套:对象和数组可多层嵌套,但需确保结构正确。
4. 示例
{
"个人资料": {
"姓名": "王五",
"年龄": 28,
"已婚": false,
"联系方式": {
"邮箱": "wangwu@example.com",
"电话": ["123-4567", "987-6543"]
}
},
"兴趣": ["旅游", "摄影"],
"备注": null
}
5. 应用场景
- 前后端数据交互:如API接口返回数据(如RESTful API)。
- 配置文件:如
package.json
(Node.js项目配置)、tsconfig.json
(TypeScript配置)。 - 本地存储:浏览器存储数据(LocalStorage)或NoSQL数据库(如MongoDB)。
- 跨平台通信:移动应用、微服务间的数据传输。
6. 与XML对比
特性 | JSON | XML |
---|---|---|
数据体积 | 更小(无闭合标签) | 较大(冗余标签) |
可读性 | 高(结构简洁) | 较低(标签嵌套复杂) |
解析速度 | 快(直接映射为数据结构) | 慢(需DOM解析) |
扩展性 | 不支持注释、命名空间等 | 支持注释、CDATA、DTD等 |
7. 注意事项
- 无注释:JSON标准不支持注释,部分解析器可能兼容,但建议通过文档说明。
- 特殊字符转义:如
\t
(制表符)、\u4E2D
(Unicode字符“中”)。 - 数值精度:大整数或高精度浮点数可能在不同语言解析时丢失精度。
8. 工具与处理
- 在线工具:JSONLint(格式校验)、JSON Formatter(格式化)。
- 编程语言支持:
- JavaScript:
JSON.parse()
和JSON.stringify()
。 - Python:
json.loads()
和json.dumps()
。 - Java:Gson、Jackson库。
- JavaScript:
JSON凭借其简洁性和高效性,已成为现代数据交换的事实标准,正确掌握其语法与结构能显著提升开发效率。
Python处理Json
在 Python 中处理 JSON 数据主要依赖标准库 json
,还有一些第三方库(如 ujson
、orjson
)提供更高性能。以下是详细说明和代码示例:
1. Python 标准库 json
核心方法:
- 序列化(Python对象 → JSON字符串/文件):
json.dumps(obj)
:将 Python 对象转为 JSON 字符串。json.dump(obj, file)
:将 Python 对象写入 JSON 文件。
- 反序列化(JSON字符串/文件 → Python对象):
json.loads(json_str)
:将 JSON 字符串转为 Python 对象。json.load(file)
:从 JSON 文件中读取并转为 Python 对象。
代码示例
(1) 基本转换
import json
# Python 字典 → JSON 字符串
data = {"name": "张三", "age": 30, "is_student": False}
json_str = json.dumps(data, ensure_ascii=False) # 禁用 ASCII 转码,支持中文
print(json_str) # 输出:{"name": "张三", "age": 30, "is_student": false}
# JSON 字符串 → Python 字典
parsed_data = json.loads(json_str)
print(parsed_data["name"]) # 输出:张三
(2) 文件读写
# 写入 JSON 文件
with open("data.json", "w", encoding="utf-8") as f:
json.dump(data, f, indent=4) # indent=4 美化格式
# 读取 JSON 文件
with open("data.json", "r", encoding="utf-8") as f:
loaded_data = json.load(f)
print(loaded_data) # 输出原字典
(3) 处理复杂对象(自定义编码/解码)
# 处理日期对象(需自定义转换)
from datetime import datetime
class CustomEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.isoformat() # 转为 ISO 格式字符串
return super().default(obj)
data = {"time": datetime.now()}
json_str = json.dumps(data, cls=CustomEncoder)
print(json_str) # 输出:{"time": "2023-10-01T12:34:56.789000"}
2. 第三方库
(1) ujson
(UltraJSON)
-
特点:解析速度极快(比标准库快 3-10 倍),适合处理大型 JSON 数据。
-
安装:
pip install ujson
-
代码:
import ujson # 用法与 json 模块一致 json_str = ujson.dumps(data) parsed_data = ujson.loads(json_str)
(2) orjson
-
特点:性能更强,支持
datetime
、UUID
等类型直接序列化,但仅兼容 Python 3.7+。 -
安装:
pip install orjson
-
代码:
import orjson # 直接处理复杂类型(如 datetime) data = {"time": datetime.now()} json_str = orjson.dumps(data).decode("utf-8") # 返回 bytes,需解码为字符串 parsed_data = orjson.loads(json_str)
(3) simplejson
-
特点:功能与标准库类似,但更新更频繁,支持
Decimal
类型。 -
安装:
pip install simplejson
-
代码:
import simplejson as json # 用法与标准库完全一致 json_str = json.dumps(data)
(4) pandas
-
特点:结合 DataFrame 处理结构化 JSON(如嵌套数组)。
-
安装:
pip install pandas
-
代码:
import pandas as pd # 从 JSON 文件读取为 DataFrame df = pd.read_json("data.json") # 将 DataFrame 保存为 JSON df.to_json("output.json", orient="records")
3. 常见问题处理
(1) 中文编码问题
-
使用
ensure_ascii=False
禁用 ASCII 转码:json.dumps({"name": "张三"}, ensure_ascii=False) # 输出:{"name": "张三"}
(2) 处理非标准类型(如类对象)
-
自定义编码器:
class User: def __init__(self, name): self.name = name def user_encoder(obj): if isinstance(obj, User): return {"name": obj.name} raise TypeError("无法序列化") user = User("李四") json_str = json.dumps(user, default=user_encoder)
(3) 解析异常处理
-
捕获
JSONDecodeError
:try: data = json.loads("{invalid_json}") except json.JSONDecodeError as e: print(f"解析错误:{e}")
4. 总结
需求场景 | 推荐工具 |
---|---|
基本 JSON 处理 | 标准库 json |
高性能解析(大数据量) | ujson 或 orjson |
复杂类型直接支持 | orjson |
结合数据分析 | pandas |
掌握这些库的使用方法后,可以灵活应对 Python 中的 JSON 数据处理需求!
Java处理Json
在 Java 生态中,处理 JSON 数据的库较多,以下是主流库的对比、代码示例、性能分析和安全性说明:
1. 主流 JSON 库及代码示例
(1) Jackson (推荐)
-
特点:高性能、功能全面(支持流式解析、树模型、注解等),社区活跃。
-
依赖:
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.15.3</version> </dependency>
-
代码示例:
import com.fasterxml.jackson.databind.ObjectMapper; // 序列化(Java对象 → JSON字符串) ObjectMapper mapper = new ObjectMapper(); User user = new User("张三", 30); String json = mapper.writeValueAsString(user); // {"name":"张三","age":30} // 反序列化(JSON字符串 → Java对象) User parsedUser = mapper.readValue(json, User.class);
(2) Gson (Google)
-
特点:简单易用,支持复杂对象嵌套,但性能略低于 Jackson。
-
依赖:
<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.10.1</version> </dependency>
-
代码示例:
import com.google.gson.Gson; Gson gson = new Gson(); String json = gson.toJson(user); // 序列化 User parsedUser = gson.fromJson(json, User.class); // 反序列化
(3) Fastjson (Alibaba)
-
特点:解析速度极快,但历史漏洞较多,需谨慎使用。
-
依赖:
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>2.0.40</version> <!-- 注意使用最新版 --> </dependency>
-
代码示例:
import com.alibaba.fastjson.JSON; String json = JSON.toJSONString(user); // 序列化 User parsedUser = JSON.parseObject(json, User.class); // 反序列化
(4) JSON-java (org.json)
-
特点:轻量级,无依赖,但功能简单,性能较低。
-
依赖:
<dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20231013</version> </dependency>
-
代码示例:
import org.json.JSONObject; JSONObject jsonObj = new JSONObject(); jsonObj.put("name", "张三"); jsonObj.put("age", 30); String json = jsonObj.toString(); JSONObject parsedObj = new JSONObject(json); String name = parsedObj.getString("name");
(5) JSON-B (Jakarta EE 标准)
-
特点:标准化接口,与 JAX-RS 集成良好,性能中等。
-
依赖:
<dependency> <groupId>jakarta.json.bind</groupId> <artifactId>jakarta.json.bind-api</artifactId> <version>3.0.0</version> </dependency> <!-- 实现库(如 Yasson) --> <dependency> <groupId>org.eclipse</groupId> <artifactId>yasson</artifactId> <version>3.0.3</version> </dependency>
-
代码示例:
import jakarta.json.bind.Jsonb; import jakarta.json.bind.JsonbBuilder; Jsonb jsonb = JsonbBuilder.create(); String json = jsonb.toJson(user); User parsedUser = jsonb.fromJson(json, User.class);
2. 性能对比
通过基准测试(如 JMH),典型性能排序如下(仅供参考):
库 | 序列化速度 | 反序列化速度 | 内存占用 | 线程安全 |
---|---|---|---|---|
Jackson | 高 | 高 | 低 | 是 |
Fastjson | 极高 | 极高 | 低 | 否(部分版本) |
Gson | 中 | 中 | 中 | 是 |
JSON-java | 低 | 低 | 高 | 是 |
JSON-B | 中 | 中 | 中 | 是 |
- Fastjson 的极致性能依赖自动类型推断,但也带来安全隐患。
- Jackson 在流式解析(
JsonParser
/JsonGenerator
)模式下性能最佳。
3. 安全性及漏洞
(1) Fastjson 漏洞
-
历史问题:Fastjson 因反序列化机制设计缺陷,多次曝出高危漏洞(如 CVE-2022-25845),攻击者可通过构造恶意 JSON 触发远程代码执行(RCE)。
-
建议:除非必要,避免使用 Fastjson;若必须使用,需升级到最新版(2.0.40+)并启用
SafeMode
:ParserConfig.getGlobalInstance().setSafeMode(true);
(2) Jackson 漏洞
-
历史问题:Jackson 曾因多态类型处理(
@JsonTypeInfo
)存在反序列化漏洞(如 CVE-2019-14379),但修复及时。 -
建议:禁用不必要的多态类型绑定:
mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
(3) 通用防范措施
- 输入过滤:对不可信的 JSON 数据严格校验。
- 依赖更新:定期升级库版本,关注安全公告(如 GitHub Advisory)。
4. 推荐选择
场景 | 推荐库 | 理由 |
---|---|---|
高性能、复杂数据处理 | Jackson | 综合性能最优,社区支持强,漏洞修复快 |
简单易用、小规模项目 | Gson | API 简单,学习成本低 |
企业级标准化开发(Jakarta EE) | JSON-B + Yasson | 符合规范,与 Jakarta EE 生态无缝集成 |
不建议使用 | Fastjson | 安全风险高,仅限内部可信场景(需严格审计) |
5. 总结代码优化技巧
-
Jackson 流式 API:处理超大 JSON 时减少内存占用:
JsonFactory factory = new JsonFactory(); try (JsonParser parser = factory.createParser(new File("data.json"))) { while (parser.nextToken() != null) { // 逐字段解析 } }
-
Gson 自定义适配器:处理特殊类型(如
LocalDateTime
):Gson gson = new GsonBuilder() .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeAdapter()) .create();
-
JSON-B 注解:通过注解控制序列化行为:
@JsonbProperty("user_name") private String name;
选择 JSON 库时,优先考虑安全性,其次平衡性能和易用性。Jackson 是大多数场景下的最佳选择。
Json生成Java类
在 Java 中,通过 JSON 数据自动生成对应的类定义(POJO)可以极大提升开发效率,以下是详细方法和工具指南:
1. 使用在线工具生成类
适用场景:快速生成简单类,无需本地环境配置。
推荐工具:
步骤:
- 输入 JSON:将 JSON 数据粘贴到工具输入框。
- 配置选项:
- 类名(Root Class Name)
- 包名(Package Name)
- 是否生成
getter
/setter
方法 - 是否使用 Lombok 注解
- 选择 JSON 库(如 Jackson、Gson)
- 生成代码:复制生成的 Java 类到项目中。
示例输入:
{
"name": "张三",
"age": 30,
"address": {
"city": "北京",
"street": "朝阳路"
},
"hobbies": ["阅读", "运动"]
}
生成代码片段:
public class Person {
private String name;
private Integer age;
private Address address;
private List<String> hobbies;
// Getters and Setters
// 或 Lombok 注解 @Data
}
public class Address {
private String city;
private String street;
}
2. 使用 IDE 插件生成类
适用场景:在 IntelliJ IDEA 或 Eclipse 中直接操作,无缝集成开发环境。
IntelliJ IDEA
- 安装插件:
Generate POJOs from JSON
(内置插件,无需额外安装)。 - 操作步骤:
- 创建新文件(如
example.json
),粘贴 JSON 数据。 - 右键点击文件 → Generate → POJOs from JSON。
- 配置包名、类名和选项(如是否生成
Builder
模式)。
- 创建新文件(如
- 生成结果:自动生成对应的 Java 类。
3. 使用构建工具插件(Maven/Gradle)
适用场景:自动化生成类,适合复杂项目或频繁更新 JSON 结构。
Maven 插件:jsonschema2pojo
步骤:
-
添加插件配置:在
pom.xml
中配置:<build> <plugins> <plugin> <groupId>org.jsonschema2pojo</groupId> <artifactId>jsonschema2pojo-maven-plugin</artifactId> <version>1.2.1</version> <configuration> <sourceDirectory>${project.basedir}/src/main/resources/json</sourceDirectory> <targetPackage>com.example.model</targetPackage> <generateBuilders>true</generateBuilders> <useLombok>true</useLombok> <!-- 支持 Lombok --> </configuration> <executions> <execution> <goals> <goal>generate</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
-
放置 JSON 文件:将 JSON 文件放在
src/main/resources/json
目录。 -
运行生成:
mvn jsonschema2pojo:generate
-
生成结果:类文件生成到
target/generated-sources/jsonschema2pojo
目录。
4. 使用代码库生成类
适用场景:通过编程动态生成类,适合需要灵活控制的场景。
Jackson + JsonNode
动态解析
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonToClassGenerator {
public static void main(String[] args) throws Exception {
String json = "{\"name\":\"张三\", \"age\":30}";
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(json);
// 手动解析 JsonNode 生成类(需自行实现字段映射)
System.out.println("public class User {");
node.fields().forEachRemaining(entry -> {
String fieldName = entry.getKey();
String fieldType = entry.getValue().getNodeType().name();
System.out.println(" private " + mapType(fieldType) + " " + fieldName + ";");
});
System.out.println("}");
}
private static String mapType(JsonNodeType type) {
return switch (type) {
case STRING -> "String";
case NUMBER -> "Integer";
case BOOLEAN -> "Boolean";
default -> "Object";
};
}
}
5. 工具对比与注意事项
方法 | 优点 | 缺点 |
---|---|---|
在线工具 | 快速、无需安装 | 无法处理敏感数据 |
IDE 插件 | 集成开发环境,操作便捷 | 依赖特定 IDE |
Maven 插件 | 自动化生成,适合项目集成 | 配置较复杂 |
动态解析 | 完全控制生成逻辑 | 需手动实现,工作量大 |
注意事项:
- 字段类型推断:工具可能无法准确推断复杂类型(如
LocalDateTime
),需手动修正。 - 命名规范:JSON 字段名中的特殊字符(如
user-name
)会被转为驼峰命名(userName
)。 - 嵌套对象:确保嵌套的 JSON 对象也能生成对应的类。
6. 最佳实践
- 结合 Lombok:生成类时启用 Lombok 的
@Data
或@Getter
/@Setter
,减少冗余代码。 - 版本控制:将生成的类纳入版本管理,避免重复生成导致冲突。
- 单元测试:生成后编写序列化/反序列化测试,验证数据映射正确性。
通过以上方法,可以快速将 JSON 数据转换为 Java 类,显著提升开发效率!
jq工具
jq
是一个功能强大的命令行 JSON 处理器,专为处理、过滤和转换 JSON 数据而设计,尤其适合在 Shell 脚本或终端中快速操作 JSON。以下是 jq 的完整使用指南,包括安装、核心语法、常用操作和示例。
1. 安装 jq
(1) Linux 系统
-
Debian/Ubuntu:
sudo apt-get install jq
-
RHEL/CentOS:
sudo yum install epel-release && sudo yum install jq # 或使用 dnf(CentOS 8+) sudo dnf install jq
-
Arch Linux:
sudo pacman -S jq
(2) macOS
-
使用 Homebrew:
brew install jq
(3) Windows
-
通过 Chocolatey:
choco install jq
-
或手动下载二进制文件:jq 官方下载
2. 基础用法
(1) 格式化 JSON
# 从文件读取并美化输出
jq '.' input.json
# 从管道输入(如 API 响应)
curl -s https://api.example.com/data | jq '.'
(2) 提取字段值
# 提取根级字段
echo '{"name": "Alice", "age": 25}' | jq '.name' # 输出:"Alice"
# 提取嵌套字段
echo '{"user": {"profile": {"email": "alice@example.com"}}}' | jq '.user.profile.email'
# 输出:"alice@example.com"
# 提取数组元素
echo '[{"id": 1}, {"id": 2}]' | jq '.[0].id' # 输出:1
(3) 处理数组
# 遍历数组元素
echo '[1, 2, 3]' | jq '.[]' # 输出:1\n2\n3
# 索引和切片
echo '[10, 20, 30, 40]' | jq '.[1:3]' # 输出:[20, 30]
3. 高级操作
(1) 条件过滤
# 筛选 age > 20 的用户
echo '[{"name": "Alice", "age": 25}, {"name": "Bob", "age": 18}]' | jq '.[] | select(.age > 20)'
# 输出:{"name": "Alice", "age": 25}
(2) 数据转换
# 映射字段
echo '{"name": "Alice", "age": 25}' | jq '{username: .name, years: .age}'
# 输出:{"username": "Alice", "years": 25}
# 合并多个字段
echo '{"first": "John", "last": "Doe"}' | jq '.name = "\(.first) \(.last)"'
# 输出:{"first": "John", "last": "Doe", "name": "John Doe"}
(3) 统计与聚合
# 计算数组长度
echo '[1, 2, 3]' | jq 'length' # 输出:3
# 求和与平均值
echo '[10, 20, 30]' | jq 'add / length' # 输出:20
(4) 处理嵌套结构
# 提取所有嵌套的 email
echo '{"users": [{"email": "a@test.com"}, {"email": "b@test.com"}]}' | jq '.users[].email'
# 输出:"a@test.com"\n"b@test.com"
4. 常用选项
选项 | 说明 |
---|---|
-r |
输出原始字符串(去除引号) |
-c |
紧凑输出(不格式化) |
-s |
将输入作为单个 JSON 数组处理 |
--arg |
传递外部变量到 jq 脚本 |
--raw-input |
将输入视为原始文本(非 JSON) |
示例:
# 使用 -r 输出无引号文本
echo '{"name": "Alice"}' | jq -r '.name' # 输出:Alice
# 通过 --arg 传递参数
echo '{"key": "value"}' | jq --arg k "key" '.[$k]' # 输出:"value"
5. 实战场景示例
(1) 提取 API 响应的特定值
curl -s https://api.github.com/users/octocat | jq '.login, .public_repos'
(2) 批量处理日志中的 JSON 数据
# 过滤包含 "error" 的日志条目
cat logs.json | jq 'select(.level == "error") | {time: .timestamp, message}'
(3) 转换 JSON 结构
# 输入:{"scores": [85, 92, 78]}
echo '{"scores": [85, 92, 78]}' | jq '{average: (.scores | add / length), max: (.scores | max)}'
# 输出:{"average": 85, "max": 92}
(4) 处理复杂嵌套 JSON
# 提取多层嵌套的 ID
echo '{"data": {"items": [{"id": "A1"}, {"id": "A2"}]}}' | jq '.data.items[].id'
# 输出:"A1"\n"A2"
6. 性能与替代工具
- 性能:jq 处理速度极快,适合处理 GB 级 JSON 文件。
- 替代工具:
fx
:交互式 JSON 查看器(Node.js 编写)。yq
:类似 jq,但支持 YAML 和 JSON。- Python +
json.tool
:简单格式化,功能较弱。
7. 学习资源
- 官方文档:jq Manual
- 交互式教程:jq Play
- Cheat Sheet:jq 常用命令速查表
掌握 jq
后,你可以轻松在命令行中完成复杂的 JSON 操作,无需依赖 Python 或 Java 脚本!