下面我将分别介绍如何在这两个主流库中遍历 JSONObject,并提供详细的代码示例和解释。
使用 org.json 库 (经典库)
这是 Java 生态中最早处理 JSON 的库之一,非常轻量级,如果你正在使用这个库,遍历方式非常直接。
添加 Maven 依赖
确保你的项目中包含 org.json 库,如果你使用 Maven,在 pom.xml 中添加:
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20251013</version> <!-- 使用最新的稳定版本 -->
</dependency>
遍历方式
org.json.JSONObject 提供了多种方法来遍历其内容,主要包括:
keys(): 获取一个包含所有键名的Iterator<String>。keySet(): 获取一个包含所有键名的Set<String>。entrySet(): 获取一个包含Map.Entry<String, Object>的Set,可以同时获取键和值。names(): 功能与keys()类似,返回一个JSONArray。
示例代码
import org.json.JSONObject;
import java.util.Iterator;
public class OrgJsonTraversalExample {
public static void main(String[] args) {
// 1. 创建一个示例 JSONObject
String jsonString = "{\"name\":\"张三\",\"age\":30,\"isStudent\":false,\"courses\":[\"数学\",\"物理\"],\"address\":{\"city\":\"北京\",\"district\":\"海淀\"}}";
JSONObject jsonObject = new JSONObject(jsonString);
System.out.println("--- 使用 keys() 和 get() 遍历 ---");
// 2. 方式一:使用 keys() 和 get()
// keys() 返回一个迭代器
Iterator<String> keys = jsonObject.keys();
while (keys.hasNext()) {
String key = keys.next();
Object value = jsonObject.get(key); // 根据键获取值
System.out.println("键: " + key + ", 值: " + value + " (值的类型: " + value.getClass().getSimpleName() + ")");
}
System.out.println("\n--- 使用 entrySet() 遍历 (推荐) ---");
// 3. 方式二:使用 entrySet() (更现代,类似 Map 遍历)
// entrySet() 返回一个 Set<Map.Entry<String, Object>>
for (java.util.Map.Entry<String, Object> entry : jsonObject.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
System.out.println("键: " + key + ", 值: " + value + " (值的类型: " + value.getClass().getSimpleName() + ")");
}
System.out.println("\n--- 遍历嵌套的 JSONObject ---");
// 4. 遍历嵌套对象
if (jsonObject.has("address")) {
JSONObject addressObject = jsonObject.getJSONObject("address");
for (String key : addressObject.keySet()) {
System.out.println("嵌套键: " + key + ", 值: " + addressObject.get(key));
}
}
System.out.println("\n--- 遍历 JSONArray ---");
// 5. 遍历 JSONArray
if (jsonObject.has("courses")) {
org.json.JSONArray coursesArray = jsonObject.getJSONArray("courses");
for (int i = 0; i < coursesArray.length(); i++) {
System.out.println("课程 " + (i + 1) + ": " + coursesArray.getString(i));
}
}
}
}
输出结果:
--- 使用 keys() 和 get() 遍历 ---
键: name, 值: 张三 (值的类型: String)
键: age, 值: 30 (值的类型: Integer)
键: isStudent, 值: false (值的类型: Boolean)
键: courses, 值: ["数学","物理"] (值的类型: JSONArray)
键: address, 值: {"city":"北京","district":"海淀"} (值的类型: JSONObject)
--- 使用 entrySet() 遍历 (推荐) ---
键: name, 值: 张三 (值的类型: String)
键: age, 值: 30 (值的类型: Integer)
键: isStudent, 值: false (值的类型: Boolean)
键: courses, 值: ["数学","物理"] (值的类型: JSONArray)
键: address, 值: {"city":"北京","district":"海淀"} (值的类型: JSONObject)
--- 遍历嵌套的 JSONObject ---
嵌套键: city, 值: 北京
嵌套键: district, 值: 海淀
--- 遍历 JSONArray ---
课程 1: 数学
课程 2: 物理
使用 com.fasterxml.jackson 库 (现代推荐)
Jackson 是目前 Java 生态中最流行、功能最强大的 JSON 处理库,它不仅能处理 JSON 字符串,还能轻松地将 JSON 与 Java 对象(POJO)进行转换。
添加 Maven 依赖
在 pom.xml 中添加 Jackson 核心库依赖:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version> <!-- 使用最新的稳定版本 -->
</dependency>
遍历方式
Jackson 的核心是 JsonNode,它代表 JSON 树模型中的一个节点,一个 JSON 对象就是一个 ObjectNode,遍历 ObjectNode 的方式与遍历 Java 的 Map 非常相似。
fields(): 返回一个Iterator<Map.Entry<String, JsonNode>>,可以同时获取键和值。keySet(): 返回一个Set<String>,包含所有键。path()或get(): 获取指定键的JsonNode。
示例代码
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Iterator;
import java.util.Map;
public class JacksonTraversalExample {
public static void main(String[] args) throws Exception {
// 1. 创建 ObjectMapper 实例
ObjectMapper objectMapper = new ObjectMapper();
// 2. 解析 JSON 字符串为 JsonNode
String jsonString = "{\"name\":\"李四\",\"age\":25,\"isStudent\":true,\"courses\":[\"历史\",\"政治\"],\"address\":{\"city\":\"上海\",\"district\":\"浦东\"}}";
JsonNode jsonNode = objectMapper.readTree(jsonString);
// 3. 检查是否是一个对象节点
if (jsonNode.isObject()) {
JsonNode rootNode = (JsonNode) jsonNode; // 可以安全地转为 ObjectNode
System.out.println("--- 使用 fields() 遍历 (推荐) ---");
// 4. 方式一:使用 fields() 遍历 (最推荐)
// fields() 返回一个迭代器,每个元素是 Map.Entry<String, JsonNode>
Iterator<Map.Entry<String, JsonNode>> fields = rootNode.fields();
while (fields.hasNext()) {
Map.Entry<String, JsonNode> entry = fields.next();
String key = entry.getKey();
JsonNode valueNode = entry.getValue();
System.out.println("键: " + key + ", 值: " + valueNode + " (值的类型: " + valueNode.getNodeType() + ")");
}
System.out.println("\n--- 使用 keySet() 和 get() 遍历 ---");
// 5. 方式二:使用 keySet() 和 get()
for (String key : rootNode.keySet()) {
JsonNode valueNode = rootNode.get(key);
System.out.println("键: " + key + ", 值: " + valueNode + " (值的类型: " + valueNode.getNodeType() + ")");
}
}
System.out.println("\n--- 遍历嵌套的 JsonNode ---");
// 6. 遍历嵌套对象
if (jsonNode.has("address")) {
JsonNode addressNode = jsonNode.get("address");
if (addressNode.isObject()) {
for (Iterator<Map.Entry<String, JsonNode>> it = addressNode.fields(); it.hasNext(); ) {
Map.Entry<String, JsonNode> entry = it.next();
System.out.println("嵌套键: " + entry.getKey() + ", 值: " + entry.getValue());
}
}
}
System.out.println("\n--- 遍历 JsonNode 数组 ---");
// 7. 遍历数组
if (jsonNode.has("courses")) {
JsonNode coursesNode = jsonNode.get("courses");
if (coursesNode.isArray()) {
for (JsonNode courseNode : coursesNode) {
System.out.println("课程: " + courseNode.asText());
}
}
}
}
}
输出结果:
--- 使用 fields() 遍历 (推荐) ---
键: name, 值: "李四" (值的类型: STRING)
键: age, 值: 25 (值的类型: NUMBER)
键: isStudent, 值: true (值的类型: BOOLEAN)
键: courses, 值: ["历史","政治"] (值的类型: ARRAY)
键: address, 值: {"city":"上海","district":"浦东"} (值的类型: OBJECT)
--- 使用 keySet() 和 get() 遍历 ---
键: name, 值: "李四" (值的类型: STRING)
键: age, 值: 25 (值的类型: NUMBER)
键: isStudent, 值: true (值的类型: BOOLEAN)
键: courses, 值: ["历史","政治"] (值的类型: ARRAY)
键: address, 值: {"city":"上海","district":"浦东"} (值的类型: OBJECT)
--- 遍历嵌套的 JsonNode ---
嵌套键: city, 值: "上海"
嵌套键: district, 值: "浦东"
--- 遍历 JsonNode 数组 ---
课程: 历史
课程: 政治
总结与对比
| 特性 | org.json |
com.fasterxml.jackson |
|---|---|---|
| 易用性 | 非常简单直观,API 直接。 | API 稍微复杂,但功能强大且规范。 |
| 性能 | 轻量级,性能足够。 | 性能非常高,是业界标准。 |
| 功能 | 专注于 JSON 的解析和构建。 | JSON-B 和 JSON-P 的参考实现,功能极其丰富,如流式 API、数据绑定、树模型等。 |
| 遍历方式 | keys(), entrySet(), keySet() |
fields(), keySet(), get() |
| 最佳实践 | 对于小型项目或简单任务,非常方便。 | 强烈推荐用于任何生产级应用,与 Spring Boot 等框架无缝集成。 |
| 获取值 | get(key) 返回 Object,需要手动类型转换(getString, getInt 等)。 |
get(key) 返回 JsonNode,提供 asText(), asInt(), asDouble() 等方法进行安全转换。 |
如何选择?
- 如果你只是需要快速、简单地解析或构建一个 JSON 字符串,不涉及复杂的对象映射,
org.json是一个不错的选择。 - 在任何现代 Java 项目中,特别是企业级应用或使用 Spring Boot 的项目,强烈推荐使用 Jackson,它的性能、功能丰富度和社区支持都更胜一筹,当你需要将 JSON 直接映射到 Java 对象(POJO)时,Jackson 的优势会体现得淋漓尽致。
