Home > Software engineering >  Why can't read a .json?
Why can't read a .json?

Time:02-15

I want to read a .json using library json-simple, my json file is:

{
    "Subjects": {
    "subject1": "MIS",
    "subject2": "DBMS",
    "subject3": "UML"
    }
}

And my code is:

import java.io.*;
import java.util.*;
import org.json.simple.*;
import org.json.simple.parser.*;
public class JSONReadFromTheFileTest {
    public static void main(String[] args) {
        JSONParser parser = new JSONParser();
        try{
            Object obj = parser.parse(new FileReader("/Users/User/Desktop/course.json"));
            JSONObject jsonObject = (JSONObject)obj;
            JSONArray subjects = (JSONArray)jsonObject.get("Subjects");
            Iterator iterator = subjects.iterator();
            while (iterator.hasNext()) {
                System.out.println(iterator.next());
            }

        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

I would like to get in console:

subject1: MIS
subject2: DBMS
subject3: UML

But instead of that, I just get the next error:

java.lang.ClassCastException: org.json.simple.JSONObject cannot be cast to org.json.simple.JSONArray
    at project.Main(Main.java:11)

But I searched in internet, and I found that if I change sintaxys of the .json in the next way:

{
    "Subjects": [
    "subject1: MIS",
    "subject2: DBMS",
    "subject3: UML"
    ]
}

I get in console what I want:

subject1: MIS
subject2: DBMS
subject3: UML

And you may think my problem is solved, but not yet, because I want to read the json file in the first way. I hope someone can help me. Thanks in advance.

CodePudding user response:

The first example shows a Subjects key containing a single object with several properties (subject1, subject2, etc).
Consider those properties like the member variables of a class. In order to let you better understand if the class is Person those variables could be name and surname.

What you try to achieve in your code is extracting a JSONArray from the JSON you are providing. Going back to the example for Person the array could be - sorry for the silly example - an Array containing phone numbers. So what you are expecting is that one of the member properties of the class is an array.

This is not possible in the first example because the first example does not contain a json array.

This line extracts the whole json object:
JSONObject jsonObject = (JSONObject)obj;

This one tries to get an array out but no array is there in the first example:
JSONArray subjects = (JSONArray)jsonObject.get("Subjects");

CodePudding user response:

Square brackets represent an array, which you've casted the getter into.

The second json shown is more correct for the code you've written, however, arrays cannot hold key-value pairs, so that's why you've made second JSON have an array of strings

To parse the first file, you'd need to start with

JSONObject subjects = (JSONObject)jsonObject.get("Subjects")

If you have full control over the file, I'd suggest just storing ["MIS", "DBMS", "UML"] then write a simple loop

for (int i = 0; i < jsonArray.length; i  ) {
  System.out.printf("subject%d: %s%n", i 1, jsonArray.get(i));
}

CodePudding user response:

To make your code work with your json, you should not use JSONArray for "Subjects" but instead JSONObject. The reason is that [ and ] indicates beginning and ending of array element in json which is represented by JSONArray. If you have { and } element then its object represented by JSONObject. zz So replace this:

JSONArray subjects = (JSONArray)jsonObject.get("Subjects");
Iterator iterator = subjects.iterator();
while (iterator.hasNext()) {
      System.out.println(iterator.next());
}

with following (I have not compiled it):

JSONObject subjects = (JSONObject)jsonObject.get("Subjects");
for(Iterator iterator = subjects.keySet().iterator(); iterator.hasNext();) {
    String key = (String) iterator.next();
    System.out.println(key   ": "   subjects.get(key));
}

CodePudding user response:

As others mentioned you should replace JSONArray with JSONObject in your code. But I would suggest to switch to different JSON library all together. I would recommend to use Json-Jackson library. Also, there is another library that provides a wrapper over Json-Jackson library. It has JsonUtils class that can simply parse your JSON in one line. Just read first your Json from file into a String jsonString and do this.

Map<String, Object> myMap = JsonUtils.readObjectFromJsonString(jsonString, Map.class);

You will get a Map with one key "Subjects" that will have a value of a Map with your 3 keys and values:

subject1: MIS
subject2: DBMS
subject3: UML

Here is the JavaDoc for the JsonUtils class. The library could be found as Maven artifact and on Github (including source code and Javadoc).

  • Related