【问题标题】:Using GSON to parse json object vs json array使用 GSON 解析 json 对象 vs json 数组
【发布时间】:2013-09-24 22:50:03
【问题描述】:

我有一个 JSON,它可以是单个对象,也可以是同一对象的数组。有没有办法使用 Gson 解析这些数据,它可以区分单个对象和数组?

我目前对此唯一的解决方案是手动解析 json 并用 try catch 包围它。首先我会尝试将其解析为单个对象,如果失败,则会抛出异常,然后我会尝试将其解析为数组。

虽然我不想手动解析它...这将花费我永远。 这是正在发生的事情的一个想法。

public class ObjectA implements Serializable{

    public String variable;
    public ObjectB[] objectb; //or ObjectB objectb;

    public ObjectA (){}
}

这里的对象可以是数组也可以是单个对象。

public class ObjectB implements Serializable{

    public String variable1;
    public String variable2;

    public ObjectB (){}
}

然后在与 json 响应交互时。我正在这样做。

Gson gson = new Gson();
ObjectA[] objectList = gson.fromJson(response, ObjectA[].class);

当 ObjectA 的数组被序列化时,json 包含 ObjectB 的数组或单个对象。

[
    {
        "variable": "blah blah",
        "objectb": {
            "variable1": "1",
            "variable2": "2"
        }
    },
    {
        "variable": "blah blah",
        "objectb": {
            "variable1": "1",
            "variable2": "2"
        }
    },
    {
        "variable": "blah blah",
        "objectb": [
            {
                "variable1": "1",
                "variable2": "2"
            },
            {
                "variable1": "1",
                "variable2": "2"
            }
        ]
    }
]

【问题讨论】:

标签: java android gson


【解决方案1】:

我刚刚将ObjectB[] 更改为List<ObjectB>ObjectA 声明。

ArrayList<ObjectA> la = new ArrayList<ObjectA>();
List<ObjectA> list = new Gson().fromJson(json, la.getClass());

for (Object a : list)
{
   System.out.println(a);
}

这是我的结果:

{variable=blah blah, objectb={variable1=1, variable2=2}}
{variable=blah blah, objectb={variable1=1, variable2=2}}
{variable=blah blah, objectb=[{variable1=1, variable2=2}, {variable1=1, variable2=2}]}

我认为在全泛型时代,如果你没有特别的需求,你可以从数组切换到列表,你有很多好处,Gson 也可以用来做灵活的解析。

【讨论】:

  • 这是答案,但现在我得到一个 IndexOutOfBoundsException 因为我认为有时它正在尝试解析它,但它是空的?我会更多地研究它。不过谢谢!
  • 随时使用完整的堆栈跟踪和代码添加关于 SO 的另一个问题。我一定会看看的。
  • 如果 "variable1","variable2" 字段是动态的,您将如何处理?这意味着,您的 ObjectB 类可能有 n 个字段。像这样的json结构:pastebin.com/uUDCKbLV
  • 对不起,多余的帖子。我想出它来处理动态数量的变量(对于我的问题^^)。我没有使用 ObjectB 类,而是使用了 ObjectA 类中的 Map 列表。像这样的东西。 public List&lt;LinkedHashMap&lt;String, String&gt;&gt; objectb = new ArrayList&lt;LinkedHashMap&lt;String, String&gt;&gt;(); ObjectA x = new Gson().fromJson(jsonString, ObjectA.class); 感谢您的想法。 :)
【解决方案2】:

尝试使用 com.google.gson.JsonParser。

        String jsonString = "object json representation";
        JsonParser jsonParser = new JsonParser();
        JsonElement jsonElement = jsonParser.parse(jsonString);

        if (jsonElement.isJsonArray()) {
            // some logic
        }

例如,使用 JsonElement 实例获取对象有多种不同的方法 - 只需使用 com.google.gson.Gson 方法:

public <T>  T fromJson(com.google.gson.JsonElement json, java.lang.Class<T> classOfT) throws com.google.gson.JsonSyntaxException 

public <T>  T fromJson(com.google.gson.JsonElement json, java.lang.reflect.Type typeOfT) throws com.google.gson.JsonSyntaxException

所以,学习 JsonElement、JsonArray、JsonPrimitive、JsonNull 和 JsonObject 类。相信,他们有足够的接口来恢复你的对象。

【讨论】:

    【解决方案3】:

    您能否通过首先尝试解析数组然后回退到解析单个对象类来尝试/捕获它?

    您也可以做一个真正简单的测试,并查看您要反序列化的字符串中的第一个非空白字符,如果它是“{”它是一个对象,如果它是一个“[”它是一个数组

    【讨论】:

    • 我正在使用一个有一堆变量的对象来序列化它。我试图通过变量解析来避免变量。
    • 这些都是同一个对象,为什么对象的内部复杂性很重要,为什么你不使用 gson 来序列化对象,这就是你使用 gson 的原因。只需查看您尝试反序列化的字符串,如果它是有效的 json,则第一个非空白字符应该告诉您您正在解析数组还是对象。
    • 查看我的编辑,当我不逐字逐句查看时,也许这会澄清我的意思。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-30
    • 1970-01-01
    • 1970-01-01
    • 2016-01-21
    • 1970-01-01
    • 2013-08-27
    • 1970-01-01
    相关资源
    最近更新 更多