【问题标题】:GSON throwing “Expected BEGIN_OBJECT but was BEGIN_ARRAY”GSON 抛出“预期为 BEGIN_OBJECT 但为 BEGIN_ARRAY”
【发布时间】:2013-11-29 11:59:54
【问题描述】:

我的班级:

public class MyClass { 

    public HashMap<Integer, HashMap<String, PointFMP[] >> matchingPages;

    public static class PointFMP{
        public float x;
        public float y;
    }
}

我的 Json:

{
    "matchingPages": {
        "1": {
            "Butter": [
                {
                    "x": 16.23,
                    "y": 21.11
                },
                {
                    "x": 18.18,
                    "y": 26.67
                }
            ],
            "Cake": [
                {
                    "x": 13.23,
                    "y": 21.11
                }
            ]
        },
        "2": {
            "Other value": [
                {
                    "x": 41.98,
                    "y": 47.62
                }
            ]
        }
    }
}

解析:

Gson gson = new GsonBuilder().create();
MyClass response = gson.fromJson(jsonString, MyClass.class);

我的错误:

11-29 12:56:47.017: W/System.err(8169): com.google.gson.JsonSyntaxException:java.lang.IllegalStateException: 应为 BEGIN_OBJECT,但在第 1 行第 1 列为 STRING 11-29 12:56:47.022:W/System.err(8169):在 com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:176)

知道如何正确解析它吗?

【问题讨论】:

  • BEGIN_OBJECT 但是是 STRING 意味着,当 gson 反序列化您的 json 时,matchingPages 键“1”是字符串而不是 int/integer,所以 gson 说它的“1”、“2”键是字符串不是整数对象。
  • 我不这么认为,因为改变 public HashMap> matchingPages;到 public HashMap> matchingPages;没有帮助,我在其他地方用公共 Map 项目解析;以下json“项目”:{“146226”:{
  • 看到我已经回复了 PointFMP 和 Butter 类,你的 json 格式是正确的。哦,我认为您没有看到 json 中的匹配页面是字符串。

标签: android json gson


【解决方案1】:

您的输入不是有效的 Json。它应该是这样的:

{
    "1": {
         "Butter": [
         {
            "x": 16.23,
            "y": 21.11
        },
        {
            "x": 18.18,
            "y": 26.67
        }
        ]
    },
    "2": {
        "Butter": [
        {
            "x": 41.98,
            "y": 47.62
        }
        ]
    }
}

【讨论】:

  • 不是这样。我刚刚复制了 json 的一部分。我已经更新了我的问题,因此可以验证 json。
  • 我接受您的回答,因为有时输入 json 似乎不正确。
【解决方案2】:

你的json格式是正确的,你可以解析如下

   public class PointFMP {

    @SerializedName(value="Butter")
    List<Butter> butter;

    @Override
    public String toString() {
        return "PointFMP [butter=" + butter + "]";
    }
}


public class Butter {

    public double x;
    public double y;
    @Override
    public String toString() {
        return "PointFMP [x=" + x + ", y=" + y + "]";
    }
}

Gson gson = new Gson();
Map<String, PointFMP> categoryMap  =
 gson.fromJson(reader, new TypeToken<Map<String, Map<String, PointFMP >>>(){}.getType());

结果如下

{1=PointFMP [butter=[PointFMP [x=16.23, y=21.11], PointFMP [x=18.18, y=26.67]]], 2=PointFMP [butter=[PointFMP [x=41.98, y=47.62]]]}

【讨论】:

  • 我无法复制粘贴您的代码,因为我的 Json 实际上比这更大(但错误出现在我在此处引用的片段中。当我在 MyClass 字段匹配页面中注释掉时,它会解析)。所以我用你的 public Map> matchingPages; 替换了我对这个变量的声明。我得到同样的错误。为什么用 PointFMP 替换 PointFMP[] ? PointFMP 是一个数组...
  • 也不允许使用@SerializedName(value="Butter"),因为值Butter 可以是任何其他字符串——它的变量值在其他请求中会有所不同。
  • 实际上在 json 匹配页面从这些大括号 {} 开始意味着它是一个对象而不是一个数组,这就是我替换它的原因。 "1" 之后的一件事:{ // 这是一个对象 "Butter":[ // 这是一个数组 { 在 Butter 数组中你有一个对象。
  • 我明白你的意思。你认为如果值“Butter”可以是任何其他字符串,是否可以解析它?
  • 是的,你可以做得更好,但是你必须编写自定义类并且你的自定义类实现了 JsonDeserializer
猜你喜欢
  • 2012-03-24
  • 2017-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多