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

Java中访问JSON嵌套值的动态方法,java,android,json,parsing,multidimensional-array,Java,Android,Json,Parsing,Multidimensional Array,我有一个JSON对象: { "maindrawer": { "enabled": true, "actions": [ { "type": "Section", "title": "Section 1" }, { "id": 1, "t

我有一个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"
                    }
                ]
            }
        ]
    }
}
这是我用来访问徽章->文本颜色值的代码:

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();
    }
}
另外,我现在对使用POJO不太感兴趣


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

由于您在本地访问json文件,这意味着您知道它的结构。 因此,与其使用-
Map data=new Gson().fromJson(json,类型)

你可以用这样的东西-

Map data=new Gson().fromJson(json,类型)

其中,
mainprawer
是一个具有成员变量-
已启用
操作
和其他类型数组的类

这将更容易获取您的值,就像使用-
mainDrawer.isEnabled()

找到了使用库所需的内容。它看起来和我需要的差不多。以下是我找到的示例代码:

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

非常干净和直接。希望这也能节省其他人的时间。

这里有两个解决方案,无需导入新库

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

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;
}

您还可以使用单行查询对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")));

您所期望的东西与上面的代码相同,只是缺少一些铸造。我很好奇java中这种东西的最新技术是什么。你发布的代码太长了。@RobertMoskal-这就是我想要实现的。在PHP中,我可以简单地传入如下内容:$data['mainprawer']['actions']['0']['badge']['textColor'];这很简单。不确定这是否可以通过JavaRelated实现:或者您可以尝试。OP不想使用POJOI,我知道它可以通过POJO实现,但这不是我的目标。是的,没有人应该创建一个类来提取单个值!加油,现在是2017年!下次我需要用java做这类事情时,我会记得的!现在看起来很有希望确定它将如何处理不同的类型,如整数、布尔值或数组等。@SolidSnake不确定您的意思。对不起,输入错误。。我的意思是我不确定第一个方法将如何处理不同的数据类型,就像我想得到整个actions数组一样。我需要将返回值转换为列表吗?@SolidSnake您可以像方法一样将其转换为
List
。谢谢,我将测试它
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();
 //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")));