Reading JSON Files from Relative Paths
Now that we have a valid JSON file, let's learn how to read it from a relative path within our Java application. Using relative paths is a good practice because it makes your code more portable across different environments.
Understanding Relative Paths in Java
A relative path is specified relative to the current working directory. In Java applications, the current working directory is typically the root directory of your project (in our case, ~/project
).
For example, if our working directory is ~/project
, then the relative path to our JSON file would be src/main/resources/data.json
.
Creating a JSON Reader Class
Let's create a Java class that reads our JSON file from a relative path:
- In the WebIDE, navigate to
~/project/src/main/java
.
- Right-click on the
java
folder and select "New File".
- Name the file
JsonReader.java
.
- Add the following code to the file:
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 {
// Specify the relative path to the JSON file
String filePath = "src/main/resources/data.json";
// Print the current working directory for reference
System.out.println("Current working directory: " + System.getProperty("user.dir"));
System.out.println("Trying to read JSON from: " + filePath);
// Read the contents of the JSON file
String jsonData = new String(Files.readAllBytes(Paths.get(filePath)));
// Print the raw JSON data
System.out.println("\nRaw JSON data:");
System.out.println(jsonData);
// Parse the JSON data into a JSONObject
JSONObject jsonObject = new JSONObject(jsonData);
// Access basic JSON data
String name = jsonObject.getString("name");
int age = jsonObject.getInt("age");
String email = jsonObject.getString("email");
boolean isEmployed = jsonObject.getBoolean("isEmployed");
// Print the extracted data
System.out.println("\nExtracted data:");
System.out.println("Name: " + name);
System.out.println("Age: " + age);
System.out.println("Email: " + email);
System.out.println("Employed: " + isEmployed);
System.out.println("\nJSON file has been successfully read and parsed.");
} catch (IOException e) {
System.out.println("Error reading JSON file: " + e.getMessage());
e.printStackTrace();
} catch (Exception e) {
System.out.println("Error parsing JSON: " + e.getMessage());
e.printStackTrace();
}
}
}
This class:
- Defines a relative path to our JSON file
- Prints the current working directory for reference
- Reads the contents of the file using
Files.readAllBytes
- Parses the JSON data into a
JSONObject
- Extracts and prints some of the data from the JSON object
The code above uses forward slashes (/
) for the file path, which works on both Unix-based systems (Linux, macOS) and Windows. However, for a more platform-independent approach, you can use the File.separator
constant:
String filePath = "src" + File.separator + "main" + File.separator + "resources" + File.separator + "data.json";
This ensures that the correct path separator is used regardless of the operating system.
Running the JSON Reader
Let's run our JSON Reader program:
cd ~/project
mvn compile
java -cp target/classes:$(mvn dependency:build-classpath -q -Dmdep.outputFile=/dev/stdout) JsonReader
You should see output similar to this:
Current working directory: /home/labex/project
Trying to read JSON from: src/main/resources/data.json
Raw JSON data:
{
"name": "John Doe",
"age": 28,
"email": "john.doe@example.com",
"isEmployed": true,
"address": {
"street": "123 Main St",
"city": "Anytown",
"zipCode": "12345"
},
"skills": ["Java", "SQL", "JavaScript", "HTML"]
}
Extracted data:
Name: John Doe
Age: 28
Email: john.doe@example.com
Employed: true
JSON file has been successfully read and parsed.
This confirms that we've successfully read our JSON file from a relative path and extracted some of the data.
Using Class Resources for Path Independence
Another common approach for reading files in Java applications is to use the class loader to access resources on the classpath. This approach is especially useful for JAR files and deployed applications.
Let's create another class that demonstrates this approach:
- In the WebIDE, navigate to
~/project/src/main/java
.
- Right-click on the
java
folder and select "New File".
- Name the file
ClasspathJsonReader.java
.
- Add the following code to the file:
import org.json.JSONObject;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
public class ClasspathJsonReader {
public static void main(String[] args) {
try {
// Get the resource as an input stream
InputStream inputStream = ClasspathJsonReader.class.getClassLoader().getResourceAsStream("data.json");
if (inputStream == null) {
System.out.println("Could not find data.json on the classpath");
return;
}
// Read the input stream into a string
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder jsonData = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
jsonData.append(line).append("\n");
}
// Parse the JSON data
JSONObject jsonObject = new JSONObject(jsonData.toString());
// Print some data
System.out.println("Name: " + jsonObject.getString("name"));
System.out.println("Age: " + jsonObject.getInt("age"));
System.out.println("JSON file successfully read from classpath.");
} catch (IOException e) {
System.out.println("Error reading JSON file: " + e.getMessage());
e.printStackTrace();
} catch (Exception e) {
System.out.println("Error parsing JSON: " + e.getMessage());
e.printStackTrace();
}
}
}
This method will work regardless of the working directory, as long as the file is on the classpath. However, we need to compile first to make the resources available on the classpath:
cd ~/project
mvn compile
java -cp target/classes:$(mvn dependency:build-classpath -q -Dmdep.outputFile=/dev/stdout) ClasspathJsonReader
You might not see the expected output because the resources aren't properly copied to the classpath during a simple compile. For a production application, you would use mvn package
to create a JAR file with all resources included.