预期BEGIN_ARRAY但在第1行第2列是BEGIN_OBJECT

时间:2014-03-29 20:09:20

标签: json gson illegalstateexception

我需要在将Json解析为实际Java对象之前找出Json中一个键的值(即type),但这样做会导致以下异常:

java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 

的Json

{
    "type":1,
    "password":"ac@123",
    "role":"normaluser",
    "name":"Archana Chatterjee",
    "username":"a.chatterjee",
    "designation":"Teacher",
    "id":"T_02",
    "age":42
}

代码

Type listType = new TypeToken<ArrayList<Pair>>() {}.getType();
ArrayList<Pair> list = gson.fromJson(json, listType);

class Pair {
    String property;
    Object value;
    // has getters and setters
}

2 个答案:

答案 0 :(得分:0)

首先,我建议你看一下Gson docsJSON specs,因为看起来你很遗憾......

使用Gson,解析JSON的正常和最简单的方法是创建一个匹配 JSON结构的Java类结构。

在这种情况下,您的JSON是一个对象(它被{ }包围)并包含许多属性(即typepasswordrole等)。

因此,您需要创建一个具有这些属性(匹配名称)的Java类:

class User
  String type
  String password
  String role
  // ...

然后你只需要调用Gson,给它一些JSON字符串并告诉它你要在哪个类中解析JSON:

User someUser = gson.fromJson( yourJson, User.class );

编辑 :如果您的JSON可能会发生变化,则无法使用单个类进行解析,因此您有两个选项。可能最简单的方法是尝试将JSON解析为Map结构。

Map是一个对象(就像您的JSON一样),其中包含 Key=>Value(例如'type'=>1)。所以你可以尝试解析它:

Type mapType = new TypeToken< Map<String, String> >() {}.getType();
HashMap<String, String> map = gson.fromJson( yourJson, mapType );

注意:这种方法的问题在于,由于Java是一种强类型语言,因此您的JSON必须具有相同类型的对(例如,)。在这种情况下,您的字段'type''age'不是字符串,而是整数,但我很确定它可以自动将它们转换为字符串...

如果不能,或者将'type''age'解析为整数非常重要,那么您唯一的选择就是写一个Custom Deserializer ......

答案 1 :(得分:-1)

阅读this后,我找到了解决问题的更好方法。在这里,我需要一个低级流式解析器来获取JsonObject

        String json3 = "{\"type\":1,\"password\":\"ac@123\",\"role\":\"normaluser\",\"name\":\"Archana Chatterjee\",\"username\":\"a.chatterjee\",\"designation\":\"Teacher\",\"id\":\"T_02\",\"age\":42}";
        JsonParser jParser = new JsonParser();
        JsonObject jObject = (JsonObject) jParser.parse(json3);

现在JsonObject能够返回密钥的值。 javadoc for same

        JsonElement elem = jObject.get("type");

JsoElement's toString()返回键的值。 (即此处类型的值)

        System.out.println(elem);

<强>输出

1