简体   繁体   English

Java读取JSON作为关联数组,例如javascript和PHP(['key'] ['subKey'])

[英]Java reading JSON as associative array like javascript and PHP ( ['key']['subKey'] )

I am writing a java program to read Json as associative array, like we do in javascript and PHP . 我正在编写一个Java程序来将Json读为关联数组,就像我们在javascriptPHP中所做的那样。 I am 90% done but problem occurs when i try to read array from Json object . 我完成了90%,但是当我尝试从Json object读取数组时出现问题。

Here is data.json file which contains student record 这是包含学生记录的data.json文件

{
"students": {
    "2334": {
        "name": {
            "firstname": "umer",
            "lastname": "farooq"
        },
        "subject": {
            "marks": {
                "maths": {
                    "total": 100.0,
                    "obtained": 70.0
                },
                "computer": {
                    "total": 100.0,
                    "obtained": 96.0
                }
            }
        },
        "lang": ["java", "javascript", "C#"]
    },
    "1003": {
        "name": {
            "firstname": "yasir",
            "lastname": "khan"
        },
        "subject": {
            "marks": {
                "maths": {
                    "total": 100.0,
                    "obtained": 80.0
                },
                "computer": {
                    "total": 100.0,
                    "obtained": 60.0
                }
            }
        },
        "lang": ["C++", "PHP", "C#"]
    },
    "1233": {
        "name": {
            "firstname": "Mubarak",
            "lastname": "Amin"
        },
        "subject": {
            "marks": {
                "maths": {
                    "total": 100.0,
                    "obtained": 70.0
                },
                "computer": {
                    "total": 100.0,
                    "obtained": 50.0
                }
            }
        },
        "lang": ["Ruby", "javascript", "C"]
    }
}

} }

To fetch marks obtained by student with the id 1233 in mathematics, i would simple pass string ['students']['1233']['subject']['marks']['maths']['obtained'] to getValue() method 为了获取数学中ID为1233的学生获得的分数,我将简单地将字符串['students']['1233']['subject']['marks']['maths']['obtained']传递给getValue()方法

     JSONAssociativeArrayReader parser = new JSONAssociativeArrayReader();
     parser.setJSONFile(new File("data.json"));
     double marksObtainedInMaths = (double) parser.getValue("['students']['1233']['subject']['marks']['maths']['obtained']");

     System.out.println("Marks obtained (maths) = " + marksObtainedInMaths);

Above code produces Marks obtained (maths) = 70.0 which is correct. 上面的代码生成的Marks obtained (maths) = 70.0 ,这是正确的。 Problem occurs when i try to fetch array from Json file via my getArray() method. 当我尝试通过getArray()方法从Json文件获取array时,会发生问题。

System.out.println("languages = " + parser.getArray("['students']['1233']['lang']") );
expected output : languages = [Ruby, javascript, C]

Following error occurs when above statement is executed 执行上面的语句时发生以下错误

    Exception in thread "main" javax.script.ScriptException: TypeError: Cannot read property "lang" from undefined in <eval> at line number 1
    at jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:467)
    at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:451)
    at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:403)
    at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:399)
    at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:155)
    at javax.script.AbstractScriptEngine.eval(Unknown Source)
    at JSONAssociativeArrayReader.getArray(Main.java:77)
    at Main.main(Main.java:30)
Caused by: <eval>:1 TypeError: Cannot read property "lang" from undefined
    at jdk.nashorn.internal.runtime.ECMAErrors.error(ECMAErrors.java:57)
    at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:213)
    at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:185)
    at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:172)
    at jdk.nashorn.internal.runtime.Undefined.get(Undefined.java:157)
    at jdk.nashorn.internal.scripts.Script$2$\^eval\_.:program(<eval>:1)
    at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:637)
    at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:494)
    at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
    at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:446)
    ... 6 more

Here is the code for JSONAssociativeArrayReader 这是JSONAssociativeArrayReader的代码

class JSONAssociativeArrayReader 
{
     private ScriptEngineManager factory;
     private ScriptEngine engine;
     private static final String JSON_OBJECT_NAME = "jsonObject";
     private static final String JSON_ARRAY_NAME = "jsonArray";


    public JSONAssociativeArrayReader() throws ScriptException
    {
        factory = new ScriptEngineManager();
        engine = factory.getEngineByName("JavaScript");
    }

    public void setJSONFile(File jsonFile) throws IOException, ScriptException
    {

        String jsonStringFromFile = "";
        if(jsonFile != null) 
        {
            BufferedReader br = new BufferedReader(new FileReader(jsonFile));
            String line = "";
            while((line = br.readLine()) != null)
            {
                jsonStringFromFile += line;
            }

        }

        engine.eval("var " + JSON_OBJECT_NAME + " = " + jsonStringFromFile);

    }

    public ArrayList<Object> getArray(String associativeArray) throws ScriptException
    {
        ArrayList<Object> objects = new ArrayList<>();

        engine.eval("var " + JSON_ARRAY_NAME + " = " + associativeArray);

        engine.eval("var arraylength = " +  JSON_ARRAY_NAME + ".length");
        int arrayLength = (int) engine.eval("arraylength");

        for (int i = 0; i < arrayLength; i++)
        {
            engine.eval(" var arrayElement = " + JSON_ARRAY_NAME + "["+i+"]");
            objects.add(engine.get("arrayElement"));
        }

        return objects;

    }



    public Object getValue(String associativeArray) throws ScriptException
    {
        return engine.eval(JSON_OBJECT_NAME+associativeArray);
    }


}

What i am doing wrong ? 我做错了什么?

As far as I can tell, your issue is at 据我所知,您的问题在

JSON_ARRAY_NAME + " = " + associativeArray);

You're forgetting the JSON_OBJECT_NAME and just assigning a var to the value of "['students']['1233']['lang']" 您忘记了JSON_OBJECT_NAME而只是将var分配给"['students']['1233']['lang']"

In other words, it needs to come to the result of 换句话说,它需要得出以下结果:

jsonObject['students']['1233']['lang']

However, in almost all JSON parsing libraries in Java, you would do something like 但是,在Java中几乎所有的JSON解析库中,您都将执行以下操作

 jsonObject.getObject("students")
    .getObject("1233")
    .getArray("lang")

Or using Gson/Jackson, you could easily write a model to implement 或使用Gson / Jackson,您可以轻松编写模型以实施

jsonObject.getStudent("1233").getLanguages()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM