在Java中访问JSON嵌套值的动态方法

时间:2017-08-18 23:41:58

标签: java android json parsing multidimensional-array

我有这个JSON对象:

{
    "maindrawer":
    {
        "enabled": true,
        "actions":
        [
            {
                "type": "Section",
                "title": "Section 1"
            },
            {
                "id": 1,
                "type": "Primary",
                "title": "Title 1",
                "badge":
                {
                    "enabled": false,
                    "value": 0,
                    "textColor": "#000000",
                    "badgeColor": "#ff0990"
                },
                "subActions":
                [
                    {
                        "id": 1,
                        "type": "Primary",
                        "title": "Sub Title 1"
                    }
                ]
            }
        ]
    }
}

这是我用来访问徽章的代码 - > textColor值:

public void loadJSONFromRaw(Context context, int id)
{
    json = null;
    try
    {
        //read and return json sting
        InputStream is = context.getResources().openRawResource(id);
        int size = is.available();
        byte[] buffer = new byte[size];
        is.read(buffer);
        is.close();
        json = new String(buffer, "UTF-8");

        //convert json to object
        Type type = new TypeToken<Map<String, Object>>() {}.getType();
        Map<String, Object> data = new Gson().fromJson(json, type);

        //access maindrawer property
        Map<String, Object> maindrawer = (Map<String, Object>)data.get("maindrawer");

        //access actions list
        List<Object> actions = (List<Object>)maindrawer.get("actions");

        //return first item in the list
        Map<String, Object> action = (Map<String, Object>) actions.get(1);

        //return badge object
        Map<String, String> badge = (Map<String, String>) action.get("badge");

        //access badge -> textColor value
        String textColor = badge.get("textColor");
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
}

使用java / android访问JSON嵌套属性是否有更好/更快或更动态的方法?我正在使用Gson库完成此任务,并且不介意切换到任何其他解决方案以使其更容易,因为这只是为了访问单个变量而编写的代码太多。

理想情况下,我正在寻找类似的东西:

String textColor = data.get("maindrawer").get("actions").get(1).get("badge").get("textColor");

此外,我现在对使用POJO不是很感兴趣。

最后,我还是Java的新手,所以我可能在这里遗漏了一些东西,或者可能有一些限制?无论如何,谢谢你的帮助!!

4 个答案:

答案 0 :(得分:4)

使用JsonPath库找到我需要的东西。看起来它与我需要的相似。这是我找到的示例代码:

String textColor = JsonPath.parse(json).read("$.maindrawer.actions[1].badge.textColor");

非常干净和直截了当。希望这也能节省别人的时间。

答案 1 :(得分:2)

由于您在本地访问json文件,这意味着您知道其结构。 所以不要使用 - Map<String, MainDrawer> data = new Gson().fromJson(json, type);

你可以使用这样的东西 -

MainDrawer

其中enabled是一个包含成员变量的类 - actionsmainDrawer.isEnabled()和另一种类型的数组。

这样可以更轻松地获取您的值,例如使用 - {{1}}

答案 2 :(得分:2)

以下是两种无需导入新库的解决方案。

编写一个简单的路径解析器:

String textColor = (String)parse(data, "maindrawer", "actions", 1, "badge", "textColor");

//...

static Object parse(Object root, Object... params) {
    Object current = root;
    for (Object p : params) {
        if (p instanceof Number) {
            current = ((List<?>)current).get(((Number)p).intValue());
        } else {
            current = ((Map<?,?>)current).get(p.toString());
        }
    }
    return current;
}

或者解析并浏览Gson的JsonElement

JsonElement root = new Gson().fromJson(json, JsonElement.class);
String textColor = root
        .getAsJsonObject().get("maindrawer")
        .getAsJsonObject().get("actions")
        .getAsJsonArray().get(1)
        .getAsJsonObject().get("badge")
        .getAsJsonObject().get("textColor")
        .getAsString();

答案 3 :(得分:0)

您也可以使用单行查询对BSON进行此操作。当您进入嵌套JSON对象时,必须将对象转换为类型。

 //import java.util.ArrayList;
 //import org.bson.Document;


 Document root = Document.parse("{ \"maindrawer\" : { \"enabled\" : true, \"actions\" : [{ \"type\" : \"Section\", \"title\" : \"Section 1\" }, { \"id\" : 1, \"type\" : \"Primary\", \"title\" : \"Title 1\", \"badge\" : { \"enabled\" : false, \"value\" : 0, \"textColor\" : \"#000000\", \"badgeColor\" : \"#ff0990\" }, \"subActions\" : [{ \"id\" : 1, \"type\" : \"Primary\", \"title\" : \"Sub Title 1\" }] }] } }");


 System.out.println(((String)((Document)((Document)((ArrayList)((Document)root.get("maindrawer")).get("actions")).get(1)).get("badge")).get("textColor")));