如何在 Java 中从相对路径读取 JSON 文件

JavaBeginner
立即练习

引言

在现代 Java 开发中,处理 JSON (JavaScript Object Notation) 是一项基本技能。JSON 因其人类可读的格式和机器易于解析的特性,已成为 Web 应用程序和 API 中数据交换的事实标准。

本教程将提供一份全面的指南,介绍如何在你的 Java 应用程序中从相对路径读取和解析 JSON 文件。你将学习如何设置一个 Maven 项目并添加必要的依赖,创建和组织一个 JSON 文件,从相对路径读取它,并解析其内容,包括复杂的嵌套数据。

在本实验结束时,你将能够熟练地在你的 Java 项目中管理 JSON 数据,这是任何处理 Web 服务、API 或配置文件开发人员的关键技能。

项目设置和 JSON 文件创建

在我们读取 JSON 文件之前,需要设置项目环境并创建文件本身。本实验使用 Apache Maven 来管理项目依赖。初始设置已经为你创建了一个标准的 Maven 项目结构。

理解项目结构

在左侧的 WebIDE 文件浏览器中,你将在 ~/project 目录下看到以下结构:

  • pom.xml: Maven 的项目对象模型 (Project Object Model) 文件。它定义了项目的依赖和构建配置。
  • src/main/java: 存放你的 Java 源代码的目录。
  • src/main/resources: 存放资源文件(如配置文件或数据文件)的目录。

pom.xml 文件已预先配置,包含了 org.json 库,这是 Java 中处理 JSON 的一个流行选择。

创建 JSON 数据文件

现在,让我们创建将在后续步骤中读取的 JSON 文件。

  1. 在 WebIDE 文件浏览器中,导航到 src/main/resources 目录。
  2. 右键单击 resources 文件夹,然后选择 "New File"。
  3. 将文件命名为 data.json
  4. 打开新创建的 data.json 文件,并添加以下内容:
{
  "name": "John Doe",
  "age": 28,
  "email": "john.doe@example.com",
  "isEmployed": true,
  "address": {
    "street": "123 Main St",
    "city": "Anytown"
  },
  "skills": ["Java", "SQL", "JavaScript"]
}

这个 JSON 文件代表了一个用户配置文件。它包含简单的键值对(如 "name": "John Doe")、一个嵌套对象 (address) 和一个字符串数组 (skills)。粘贴内容后请保存文件。

你现在已成功设置了项目并创建了 JSON 数据文件。在下一步中,我们将编写 Java 代码来读取和解析此文件。

读取和解析简单的 JSON 文件

在准备好 JSON 文件后,我们现在可以编写一个 Java 程序来读取它。我们将使用相对路径,这是一种常见的做法,可以确保应用程序在不同环境中具有可移植性。

理解相对路径

相对路径是相对于当前工作目录指定的。当从终端运行 Maven 项目时,工作目录通常是项目的根文件夹,在本例中是 ~/project。因此,到我们 JSON 文件的相对路径是 src/main/resources/data.json

创建 Java JSON 读取器

让我们创建一个 Java 类来读取文件。

  1. 在 WebIDE 文件浏览器中,导航到 src/main/java/com/labex
  2. 右键单击 com/labex 文件夹,然后选择 "New File"。
  3. 将文件命名为 JsonReader.java
  4. 打开文件并添加以下 Java 代码:
package com.labex;

import org.json.JSONObject;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

public class JsonReader {
    public static void main(String[] args) {
        try {
            // 定义 JSON 文件的相对路径
            String filePath = "src/main/resources/data.json";
            System.out.println("Reading file from: " + filePath);

            // 将文件内容读取到字符串中
            String content = new String(Files.readAllBytes(Paths.get(filePath)));

            // 从字符串内容创建 JSONObject
            JSONObject jsonObject = new JSONObject(content);

            // 访问并打印简单键的值
            String name = jsonObject.getString("name");
            int age = jsonObject.getInt("age");
            boolean isEmployed = jsonObject.getBoolean("isEmployed");

            System.out.println("\n--- Parsed JSON Data ---");
            System.out.println("Name: " + name);
            System.out.println("Age: " + age);
            System.out.println("Is Employed: " + isEmployed);

        } catch (IOException e) {
            System.out.println("Error reading file: " + e.getMessage());
        } catch (Exception e) {
            System.out.println("Error parsing JSON: " + e.getMessage());
        }
    }
}

代码解释

  • package com.labex;: 声明该类属于 com.labex 包,遵循标准的 Java 约定。
  • String filePath = "src/main/resources/data.json";: 定义文件的相对路径。
  • Files.readAllBytes(Paths.get(filePath)): 将文件的全部内容读取到一个字节数组中,然后将其转换为 String
  • new JSONObject(content): 将包含 JSON 数据的字符串解析为 JSONObject
  • jsonObject.getString("name"): 检索与键 "name" 相关联的字符串值。getInt()getBoolean() 等类似方法用于其他数据类型。

编译和运行程序

现在,让我们使用 Maven 来编译和运行我们的代码。

  1. 在 WebIDE 中打开终端。
  2. 运行以下命令来编译并执行你的类:
mvn compile exec:java -Dexec.mainClass="com.labex.JsonReader"

你将在终端中看到以下输出:

Reading file from: src/main/resources/data.json

--- Parsed JSON Data ---
Name: John Doe
Age: 28
Is Employed: true

此输出确认你的程序已成功从相对路径读取了 data.json 文件并解析了其基本属性。

处理复杂的 JSON 数据

真实的 JSON 数据通常包含嵌套结构,例如对象中的对象或值的数组。我们的 data.json 文件包含一个嵌套的 address 对象和一个 skills 数组。让我们扩展知识来解析这些复杂的结构。

创建复杂的 JSON 解析器

我们将创建一个新类来演示解析 JSON 文件中这些更复杂的部份。

  1. 在 WebIDE 文件浏览器中,导航到 src/main/java/com/labex
  2. 创建一个名为 ComplexJsonParser.java 的新文件。
  3. 将以下代码添加到文件中:
package com.labex;

import org.json.JSONArray;
import org.json.JSONObject;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

public class ComplexJsonParser {
    public static void main(String[] args) {
        try {
            String filePath = "src/main/resources/data.json";
            String content = new String(Files.readAllBytes(Paths.get(filePath)));
            JSONObject person = new JSONObject(content);

            System.out.println("--- Parsing Complex JSON Data ---");

            // 访问嵌套的 'address' 对象
            JSONObject address = person.getJSONObject("address");
            String street = address.getString("street");
            String city = address.getString("city");

            System.out.println("\nAddress:");
            System.out.println("  Street: " + street);
            System.out.println("  City: " + city);

            // 访问 'skills' 数组
            JSONArray skills = person.getJSONArray("skills");
            System.out.println("\nSkills:");
            for (int i = 0; i < skills.length(); i++) {
                String skill = skills.getString(i);
                System.out.println("  - " + skill);
            }

        } catch (IOException e) {
            System.out.println("Error reading file: " + e.getMessage());
        } catch (Exception e) {
            System.out.println("Error parsing JSON: " + e.getMessage());
        }
    }
}

代码解释

  • person.getJSONObject("address"): 此方法检索与键 "address" 相关联的嵌套 JSON 对象。然后,你可以在这个新的 JSONObject 上调用 getString() 等方法。
  • person.getJSONArray("skills"): 此方法检索与键 "skills" 相关联的 JSON 数组。
  • skills.length(): 返回 JSONArray 中的元素数量。
  • skills.getString(i): 检索 JSONArray 中特定索引 i 处的字符串元素。

编译和运行解析器

让我们运行这个新类来查看输出。

  1. 在 WebIDE 中打开终端。
  2. 执行以下命令:
mvn compile exec:java -Dexec.mainClass="com.labex.ComplexJsonParser"

预期的输出是:

--- Parsing Complex JSON Data ---

Address:
  Street: 123 Main St
  City: Anytown

Skills:
  - Java
  - SQL
  - JavaScript

这展示了你处理 JSON 结构中嵌套对象和数组的能力,这是处理复杂数据源和 API 响应的关键技能。

创建可重用的 JSON 工具

在软件开发中,编写可重用代码是一种最佳实践。与其在每个需要它的类中重复文件读取逻辑,不如创建一个工具类。这种方法被称为“不要重复自己”(DRY),它可以使你的代码更简洁、更易于维护,并且不易出错。

创建 JsonUtils

让我们创建一个工具类来封装读取 JSON 文件的逻辑。

  1. 在 WebIDE 中,在 src/main/java/com/labex 目录下创建一个名为 JsonUtils.java 的新文件。
  2. 添加以下代码:
package com.labex;

import org.json.JSONObject;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

public class JsonUtils {

    /**
     * 从相对路径读取 JSON 文件并将其解析为 JSONObject。
     *
     * @param filePath JSON 文件的相对路径。
     * @return 表示文件内容的 JSONObject。
     * @throws IOException 如果在读取文件时发生 I/O 错误。
     */
    public static JSONObject readJsonObjectFromFile(String filePath) throws IOException {
        String content = new String(Files.readAllBytes(Paths.get(filePath)));
        return new JSONObject(content);
    }
}

这个类包含一个 static 方法 readJsonObjectFromFilestatic 方法属于类本身而不是实例,因此你可以直接使用类名(例如 JsonUtils.readJsonObjectFromFile(...))调用它,而无需创建对象。

使用工具类

现在,让我们创建一个主应用程序类来使用我们新的工具。

  1. 在 WebIDE 中,在 src/main/java/com/labex 目录下创建一个名为 Main.java 的新文件。
  2. 将以下代码添加到 Main.java
package com.labex;

import org.json.JSONObject;

public class Main {
    public static void main(String[] args) {
        try {
            // 使用工具类读取 JSON 文件
            JSONObject data = JsonUtils.readJsonObjectFromFile("src/main/resources/data.json");

            // 现在我们可以像以前一样使用 JSONObject
            String name = data.getString("name");
            String city = data.getJSONObject("address").getString("city");

            System.out.println("--- 使用 JsonUtils 读取的数据 ---");
            System.out.println("Name: " + name);
            System.out.println("City: " + city);
            System.out.println("\n成功使用 JsonUtils 读取 JSON。");

        } catch (Exception e) {
            System.out.println("发生错误:" + e.getMessage());
        }
    }
}

这个 Main 类更加简洁。它将读取和解析文件的任务委托给 JsonUtils,只关注如何处理生成的 JSONObject

运行主应用程序

最后,让我们运行我们的 Main 类。

  1. 在 WebIDE 中打开终端。
  2. 执行以下命令:
mvn compile exec:java -Dexec.mainClass="com.labex.Main"

你将看到以下输出:

--- 使用 JsonUtils 读取的数据 ---
Name: John Doe
City: Anytown

成功使用 JsonUtils 读取 JSON。

通过创建工具类,你使代码更加模块化和可重用,这是有效软件工程的关键原则。

总结

在本实验中,你获得了在 Java 中处理 JSON 文件的实践技能。你从基本设置进展到高级解析技术,最终完成了可重用代码的创建。

以下是你学到的内容回顾:

  • 项目设置: 你学会了如何构建一个 Maven 项目并包含外部库,如 org.json,以便处理 JSON。
  • JSON 文件创建: 你创建了一个格式良好的 JSON 文件,其中包含各种数据类型,包括字符串、数字、布尔值、嵌套对象和数组。
  • 从相对路径读取: 你成功地使用相对路径读取了一个文件,这项技术使应用程序更具可移植性。
  • 解析 JSON: 你使用 org.json 库将 JSON 字符串解析为 JSONObjectJSONArray 对象,从而允许你以编程方式访问数据。
  • 处理复杂结构: 你学会了如何导航嵌套的 JSON 对象和遍历 JSON 数组来提取复杂数据。
  • 代码可重用性: 你通过创建 JsonUtils 类来封装文件读取逻辑,应用了 DRY(Don't Repeat Yourself)原则,从而实现了更简洁、更易于维护的代码。

对于任何涉及 Web 服务、API 集成或应用程序配置的 Java 开发人员来说,读取、解析和操作 JSON 数据都是一项基本技能。你在本实验中打下的基础,在你应对更复杂的开发挑战时将是无价的。