How to read JSON file from relative path in Java

JavaJavaBeginner
Jetzt üben

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Introduction

In modern Java development, handling JSON (JavaScript Object Notation) is a fundamental skill. JSON is the de facto standard for data exchange in web applications and APIs due to its human-readable format and ease of parsing by machines.

This tutorial provides a comprehensive guide to reading and parsing JSON files from a relative path in your Java applications. You will learn how to set up a Maven project with the necessary dependencies, create and structure a JSON file, read it from a relative path, and parse its contents, including complex nested data.

By the end of this lab, you will be proficient in managing JSON data within your Java projects, a critical skill for any developer working with web services, APIs, or configuration files.

Project Setup and JSON File Creation

Before we can read a JSON file, we need to set up our project environment and create the file itself. This lab uses Apache Maven to manage project dependencies. The initial setup has already created a standard Maven project structure for you.

Understanding the Project Structure

In the WebIDE file explorer on the left, you will see the following structure inside the ~/project directory:

  • pom.xml: The Project Object Model file for Maven. It defines the project's dependencies and build configurations.
  • src/main/java: The directory for your Java source code.
  • src/main/resources: The directory for resource files, such as configuration or data files.

The pom.xml file has been pre-configured to include the org.json library, a popular choice for working with JSON in Java.

Creating the JSON Data File

Now, let's create the JSON file that we will read in the subsequent steps.

  1. In the WebIDE file explorer, navigate to the src/main/resources directory.
  2. Right-click on the resources folder and select "New File".
  3. Name the file data.json.
  4. Open the newly created data.json file and add the following content:
{
  "name": "John Doe",
  "age": 28,
  "email": "[email protected]",
  "isEmployed": true,
  "address": {
    "street": "123 Main St",
    "city": "Anytown"
  },
  "skills": ["Java", "SQL", "JavaScript"]
}

This JSON file represents a user profile. It contains simple key-value pairs (like "name": "John Doe"), a nested object (address), and an array of strings (skills). Save the file after pasting the content.

You have now successfully set up the project and created the JSON data file. In the next step, we will write Java code to read and parse this file.

Reading and Parsing a Simple JSON File

With our JSON file in place, we can now write a Java program to read it. We will use a relative path, which is a common practice to ensure the application is portable across different environments.

Understanding Relative Paths

A relative path is specified from the current working directory. When running a Maven project from the terminal, the working directory is typically the project's root folder, which is ~/project in our case. Therefore, the relative path to our JSON file is src/main/resources/data.json.

Creating the Java JSON Reader

Let's create a Java class to read the file.

  1. In the WebIDE file explorer, navigate to src/main/java/com/labex.
  2. Right-click on the com/labex folder and select "New File".
  3. Name the file JsonReader.java.
  4. Open the file and add the following Java code:
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 {
            // Define the relative path to the JSON file
            String filePath = "src/main/resources/data.json";
            System.out.println("Reading file from: " + filePath);

            // Read the file content into a string
            String content = new String(Files.readAllBytes(Paths.get(filePath)));

            // Create a JSONObject from the string content
            JSONObject jsonObject = new JSONObject(content);

            // Access and print the values of simple keys
            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());
        }
    }
}

Code Explanation

  • package com.labex;: Declares that this class belongs to the com.labex package, following standard Java conventions.
  • String filePath = "src/main/resources/data.json";: Defines the relative path to our file.
  • Files.readAllBytes(Paths.get(filePath)): Reads the entire content of the file into a byte array, which is then converted to a String.
  • new JSONObject(content): Parses the string containing JSON data into a JSONObject.
  • jsonObject.getString("name"): Retrieves the string value associated with the key "name". Similar methods like getInt() and getBoolean() are used for other data types.

Compiling and Running the Program

Now, let's compile and run our code using Maven.

  1. Open the terminal in the WebIDE.
  2. Run the following command to compile and execute your class:
mvn compile exec:java -Dexec.mainClass="com.labex.JsonReader"

You should see the following output in the terminal:

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

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

This output confirms that your program successfully read the data.json file from its relative path and parsed its basic properties.

Handling Complex JSON Data

Real-world JSON data often contains nested structures, such as objects within objects or arrays of values. Our data.json file includes a nested address object and a skills array. Let's extend our knowledge to parse these complex structures.

Creating a Complex JSON Parser

We will create a new class to demonstrate parsing these more complex parts of the JSON file.

  1. In the WebIDE file explorer, navigate to src/main/java/com/labex.
  2. Create a new file named ComplexJsonParser.java.
  3. Add the following code to the file:
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 ---");

            // Access the nested 'address' object
            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);

            // Access the 'skills' array
            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());
        }
    }
}

Code Explanation

  • person.getJSONObject("address"): This method retrieves the nested JSON object associated with the key "address". You can then call methods like getString() on this new JSONObject.
  • person.getJSONArray("skills"): This method retrieves the JSON array associated with the key "skills".
  • skills.length(): Returns the number of elements in the JSONArray.
  • skills.getString(i): Retrieves the string element at a specific index i within the JSONArray.

Compiling and Running the Parser

Let's run this new class to see the output.

  1. Open the terminal in the WebIDE.
  2. Execute the following command:
mvn compile exec:java -Dexec.mainClass="com.labex.ComplexJsonParser"

The expected output is:

--- Parsing Complex JSON Data ---

Address:
  Street: 123 Main St
  City: Anytown

Skills:
  - Java
  - SQL
  - JavaScript

This demonstrates your ability to navigate and extract data from nested objects and arrays within a JSON structure, a crucial skill for handling complex data feeds and API responses.

Creating a Reusable JSON Utility

In software development, it is a best practice to write reusable code. Instead of repeating the file-reading logic in every class that needs it, we can create a utility class. This approach, known as "Don't Repeat Yourself" (DRY), makes your code cleaner, more maintainable, and less prone to errors.

Creating the JsonUtils Class

Let's create a utility class to encapsulate the logic for reading a JSON file.

  1. In the WebIDE, create a new file named JsonUtils.java inside the src/main/java/com/labex directory.
  2. Add the following code:
package com.labex;

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

public class JsonUtils {

    /**
     * Reads a JSON file from a relative path and parses it into a JSONObject.
     *
     * @param filePath The relative path to the JSON file.
     * @return A JSONObject representing the file's content.
     * @throws IOException if an I/O error occurs reading from the file.
     */
    public static JSONObject readJsonObjectFromFile(String filePath) throws IOException {
        String content = new String(Files.readAllBytes(Paths.get(filePath)));
        return new JSONObject(content);
    }
}

This class contains a single static method, readJsonObjectFromFile. A static method belongs to the class itself rather than an instance, so you can call it directly using the class name (e.g., JsonUtils.readJsonObjectFromFile(...)) without creating an object.

Using the Utility Class

Now, let's create a main application class that uses our new utility.

  1. In the WebIDE, create a new file named Main.java inside the src/main/java/com/labex directory.
  2. Add the following code to Main.java:
package com.labex;

import org.json.JSONObject;

public class Main {
    public static void main(String[] args) {
        try {
            // Use the utility class to read the JSON file
            JSONObject data = JsonUtils.readJsonObjectFromFile("src/main/resources/data.json");

            // Now we can work with the JSONObject as before
            String name = data.getString("name");
            String city = data.getJSONObject("address").getString("city");

            System.out.println("--- Data read using JsonUtils ---");
            System.out.println("Name: " + name);
            System.out.println("City: " + city);
            System.out.println("\nSuccessfully read JSON using JsonUtils.");

        } catch (Exception e) {
            System.out.println("An error occurred: " + e.getMessage());
        }
    }
}

This Main class is much cleaner. It delegates the task of reading and parsing the file to JsonUtils, focusing only on what to do with the resulting JSONObject.

Running the Main Application

Finally, let's run our Main class.

  1. Open the terminal in the WebIDE.
  2. Execute the following command:
mvn compile exec:java -Dexec.mainClass="com.labex.Main"

You will see the following output:

--- Data read using JsonUtils ---
Name: John Doe
City: Anytown

Successfully read JSON using JsonUtils.

By creating a utility class, you have made your code more modular and reusable, which is a key principle of effective software engineering.

Summary

In this lab, you have acquired practical skills for handling JSON files in Java. You progressed from basic setup to advanced parsing techniques, culminating in the creation of reusable code.

Here is a recap of what you have learned:

  • Project Setup: You learned how to structure a Maven project and include external libraries like org.json to work with JSON.
  • JSON File Creation: You created a well-formed JSON file containing various data types, including strings, numbers, booleans, nested objects, and arrays.
  • Reading from a Relative Path: You successfully read a file using a relative path, a technique that makes applications more portable.
  • Parsing JSON: You used the org.json library to parse JSON strings into JSONObject and JSONArray objects, allowing you to access the data programmatically.
  • Handling Complex Structures: You learned how to navigate nested JSON objects and iterate over JSON arrays to extract complex data.
  • Code Reusability: You applied the DRY (Don't Repeat Yourself) principle by creating a JsonUtils class to encapsulate file-reading logic, leading to cleaner and more maintainable code.

The ability to read, parse, and manipulate JSON data is essential for any Java developer involved in web services, API integration, or application configuration. The foundation you have built in this lab will be invaluable as you tackle more complex development challenges.