LarryDpk
发布于 2025-04-12 / 11 阅读
0

Json介绍

JSON格式

Json介绍

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,以其简洁的结构和高效的解析能力广泛应用于各种场景。以下是对JSON格式的详细介绍:


1. 基本结构

JSON由两种基础结构组成:

  • 对象(Object):用大括号 {} 包裹,表示键值对集合。键名(字符串)与值之间用冒号 : 分隔,键值对之间用逗号 , 分隔。

    {
      "name": "李四",
      "age": 25
    }
    
  • 数组(Array):用方括号 [] 包裹,表示值的有序列表,元素间用逗号 , 分隔。

    ["苹果", "香蕉", "橘子"]
    

2. 数据类型

JSON支持以下数据类型:

  • 字符串(String):双引号包裹,支持转义字符(如 \"\n)。
  • 数字(Number):整数或浮点数(如 423.14)。
  • 布尔值(Boolean)truefalse
  • 空值(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库。

JSON凭借其简洁性和高效性,已成为现代数据交换的事实标准,正确掌握其语法与结构能显著提升开发效率。

Python处理Json

在 Python 中处理 JSON 数据主要依赖标准库 json,还有一些第三方库(如 ujsonorjson)提供更高性能。以下是详细说明和代码示例:


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

  • 特点:性能更强,支持 datetimeUUID 等类型直接序列化,但仅兼容 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
高性能解析(大数据量) ujsonorjson
复杂类型直接支持 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. 使用在线工具生成类

适用场景:快速生成简单类,无需本地环境配置。
推荐工具

步骤

  1. 输入 JSON:将 JSON 数据粘贴到工具输入框。
  2. 配置选项
    • 类名(Root Class Name)
    • 包名(Package Name)
    • 是否生成 getter/setter 方法
    • 是否使用 Lombok 注解
    • 选择 JSON 库(如 Jackson、Gson)
  3. 生成代码:复制生成的 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

  1. 安装插件Generate POJOs from JSON(内置插件,无需额外安装)。
  2. 操作步骤
    • 创建新文件(如 example.json),粘贴 JSON 数据。
    • 右键点击文件 → GeneratePOJOs from JSON
    • 配置包名、类名和选项(如是否生成 Builder 模式)。
  3. 生成结果:自动生成对应的 Java 类。

3. 使用构建工具插件(Maven/Gradle)

适用场景:自动化生成类,适合复杂项目或频繁更新 JSON 结构。

Maven 插件:jsonschema2pojo

步骤

  1. 添加插件配置:在 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>
    
  2. 放置 JSON 文件:将 JSON 文件放在 src/main/resources/json 目录。

  3. 运行生成

    mvn jsonschema2pojo:generate
    
  4. 生成结果:类文件生成到 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 插件 自动化生成,适合项目集成 配置较复杂
动态解析 完全控制生成逻辑 需手动实现,工作量大

注意事项

  1. 字段类型推断:工具可能无法准确推断复杂类型(如 LocalDateTime),需手动修正。
  2. 命名规范:JSON 字段名中的特殊字符(如 user-name)会被转为驼峰命名(userName)。
  3. 嵌套对象:确保嵌套的 JSON 对象也能生成对应的类。

6. 最佳实践

  1. 结合 Lombok:生成类时启用 Lombok 的 @Data@Getter/@Setter,减少冗余代码。
  2. 版本控制:将生成的类纳入版本管理,避免重复生成导致冲突。
  3. 单元测试:生成后编写序列化/反序列化测试,验证数据映射正确性。

通过以上方法,可以快速将 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 后,你可以轻松在命令行中完成复杂的 JSON 操作,无需依赖 Python 或 Java 脚本!