java GSON 期望 BEGIN_ARRAY 但 BEGIN_OBJECT?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31570343/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 18:48:42  来源:igfitidea点击:

GSON Expected BEGIN_ARRAY but was BEGIN_OBJECT?

javaandroidweb-servicesgson

提问by Slasch

I just start to learn about gson. I see lot of topic about this error, but i don't find any help or answer corresponding of my problem.

我刚开始学习gson。我看到很多关于这个错误的话题,但我没有找到与我的问题相对应的任何帮助或答案。

I'm trying to parse a JSON string like this one:

我正在尝试解析这样的 JSON 字符串:

{
"CodeAnalytique": "XXXX",
  "Domaine": "XXXX",
  "HabilitationAD": [
    {
      "Key": "XXXX",
      "Value": [
        {
          "Applicatif": "XXXX",
          "Cle": "E",
          "Role": "Red",
          "Valeur": "XXXX"
        },
        {
          "Applicatif": "XXXX",
          "Cle": "E",
          "Role": "Red",
          "Valeur": "XXXX"
        }
        //lot of other value
        ]
    }
  ],
  "HabilitationInterprete": [
    {
      "Key": "XX",
      "Value": [
        {
          "Applicatif": "XXXX",
          "Cle": "Z",
          "Role": "Red",
          "Valeur": "XXX"
        },
        {
          "Applicatif": "XXXX",
          "Cle": "Z",
          "Role": "Red",
          "Valeur": "XXXX"
        }
        //lot of other value
        ]
    }
  ],
  "Identity": "XXXX",
  "InfoConsolidee": "Operation requested at XXXX",
  "IsAdminI": true,
  "IsAdminM": false,
  "IsAuthentif": true,
  "Matricule": "XXX",
  "Nom": "XXXX",
  "PasswordEnvoye": "XXXX",
  "Prenom": "XXX",
  "PrincipalPermissionMode": 1,
  "RoleSGBD": [
    "xxxx"
  ],
  "RoleSI": [
    null,
    "APP_02",
    "APP_03",
   //lot of other value
  ],
  "Societe": "XXX",
  "TypeClient": null
}

into an objects

成一个对象

InfoSecuriteBean mInfoSecuriteBean = gson.fromJson(reader, InfoSecuriteBean.class);

Here's object class I'm using.

这是我正在使用的对象类。

import com.google.gson.annotations.SerializedName;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class InfoSecuriteBean {

    @SerializedName("IsAuthentif")
    private boolean mIsAuthentif = false;

    @SerializedName("PrincipalPermissionMode")
    private enumPrincipalPermissionMode mPrincipalPermissionMode;
    @SerializedName("RoleSGBD")
    private List<String> mRoleSGBD;
    @SerializedName("RoleSI")
    private List<String> mRoleSI;
    @SerializedName("Identity")
    private String mIdentity = null;
    @SerializedName("Password")
    private String mPassword = null;
    @SerializedName("InfoConsolidee")
    private String mInfoConsolidee = null;

    @SerializedName("IsAdminM")
    private boolean mIsAdminM = false;
    @SerializedName("IsAdminI")
    private boolean mIsAdminI = false;

    @SerializedName("Matricule")
    private String mMatricule = null;
    @SerializedName("Nom")
    private String mNom = null;
    @SerializedName("Prenom")
    private String mPrenom = null;
    @SerializedName("CodeAnalytique")
    private String mCodeAnalytique = null;
    @SerializedName("Domaine")
    private String mDomaine = null;
    @SerializedName("Societe")
    private String mSociete = null;
    @SerializedName("TypeClient")
    private String mTypeClient = null;

    @SerializedName("HabilitationAD")
    private Map<String,List<HabilitationBean>> mHabilitationAD = new HashMap<String, List<HabilitationBean>>();
    @SerializedName("HabilitationInterprete")
    private Map<String,List<HabilitationBean>> mHabilitationInterprete = new HashMap<String, List<HabilitationBean>>();
//Getter and setter

and the other object use

和另一个对象使用

import com.google.gson.annotations.SerializedName;

public class HabilitationBean
{
    @SerializedName("Applicatif")
    private String mApplicatif = null;
    @SerializedName("Role")
    private String mRole = null;
    @SerializedName("Cle")
    private String mCle = null;
    @SerializedName("Valeur")
    private String mValeur = null;

//getter and setter

But it throws me with

但它让我感到

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECTat line 1 column 60

Any ideas how should I fix it?

任何想法我应该如何解决它?

Thanks!

谢谢!

EDIT

编辑

Caused by: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 60 path $.HabilitationAD[0]
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:200)
            at com.google.gson.Gson.fromJson(Gson.java:810)
            at com.google.gson.Gson.fromJson(Gson.java:748)
            at com.sig.webservice.WebSecurityGBD.doInBackground(WebSecurityGBD.java:69)
            at com.sig.webservice.WebSecurityGBD.doInBackground(WebSecurityGBD.java:23)
            at android.os.AsyncTask.call(AsyncTask.java:292)
            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
????????????at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:231)
????????????at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
????????????at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
????????????at java.lang.Thread.run(Thread.java:818)
     Caused by: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 60 path $.HabilitationAD[0]
            at com.google.gson.stream.JsonReader.beginArray(JsonReader.java:350)
            at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:172)
            at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:145)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.read(ReflectiveTypeAdapterFactory.java:103)
            at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:196)
????????????at com.google.gson.Gson.fromJson(Gson.java:810)
????????????at com.google.gson.Gson.fromJson(Gson.java:748)
????????????at com.sig.webservice.WebSecurityGBD.doInBackground(WebSecurityGBD.java:69)
????????????at com.sig.webservice.WebSecurityGBD.doInBackground(WebSecurityGBD.java:23)
????????????at android.os.AsyncTask.call(AsyncTask.java:292)
????????????at java.util.concurrent.FutureTask.run(FutureTask.java:237)
????????????at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:231)
????????????at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
????????????at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
????????????at java.lang.Thread.run(Thread.java:818)

EDIT 2

编辑 2

The problem come from the two HashMap>

问题出在两个HashMap>

 @SerializedName("HabilitationAD")
        private Map<String,List<HabilitationBean>> mHabilitationAD = new HashMap<String, List<HabilitationBean>>();
        @SerializedName("HabilitationInterprete")
        private Map<String,List<HabilitationBean>> mHabilitationInterprete = new HashMap<String, List<HabilitationBean>>(); 

if i comment this properties i don't have any probleme to build my json objet.

如果我评论这个属性,我就没有任何问题来构建我的 json 对象。

I found this link Deserializing a Map<String, Object> field with Gson

我发现这个链接用 Gson 反序列化一个 Map<String, Object> 字段

Currently i try something like this

目前我尝试这样的事情

public class InfoSecuriteBeanDeserializer implements JsonDeserializer<InfoSecuriteBean> {

    @Override
    public InfoSecuriteBean deserialize(JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {

        JsonArray jArray = (JsonArray) json;

        InfoSecuriteBean mInfoSecuriteBean = new InfoSecuriteBean();

        for (int i=1; i<jArray.size(); i++) {
            JsonObject jObject = (JsonObject) jArray.get(i);
            //assuming you have the suitable constructor...
            HabilitationBean mHabilitationBean = new HabilitationBean(jObject.get("Applicatif").getAsString(),
                    jObject.get("Cle").getAsString(),
                    jObject.get("Role").getAsString(),
                    jObject.get("Valeur").getAsString());
            mInfoSecuriteBean.getmHabilitationAD().add(mHabilitationBean);
        }

        return mInfoSecuriteBean;
    }
}

Do you think i'm in the good way to resolve my problem ?

你认为我能很好地解决我的问题吗?

回答by Jesse Wilson

Upgrade to the latest Gson and it'll tell you exactly where there's a mismatch. Typically this happens when your model has a Listbut your JSON doesn't (ie. no [...]).

升级到最新的 Gson,它会准确地告诉您哪里不匹配。通常,当您的模型有 aList但您的 JSON 没有(即 no [...])时,会发生这种情况。

回答by Slasch

I found a simply solution for solve my problem. I will show here my solution, maybe this will help some people.

我找到了一个简单的解决方案来解决我的问题。我会在这里展示我的解决方案,也许这会帮助一些人。

So I created two new class : HabilitationAD and HabilitationInterprete

所以我创建了两个新类:HabilitationAD 和 HabilitationInterprete

public class HabilitationAD {

    @SerializedName("Key")
    private String mKey;

    @SerializedName("Value")
    private List<BeanHabilitation> mValue;

    public String getmKey() {
        return mKey;
    }

    public void setmKey(String mKey) {
        this.mKey = mKey;
    }

    public List<BeanHabilitation> getmValue() {
        return mValue;
    }

    public void setmValue(List<BeanHabilitation> mValue) {
        this.mValue = mValue;
    }

    public HabilitationAD(){

    }

    public HabilitationAD(String p_mKey, List<BeanHabilitation> p_mValue){
        this.mKey = p_mKey;
        this.mValue = p_mValue;
    }
}

and :

和 :

    public class HabilitationInterprete {

        @SerializedName("Key")
        private String mKey;

        @SerializedName("Value")
        private List<BeanHabilitation> mValue;

        public String getmKey() {
            return mKey;
        }

        public void setmKey(String mKey) {
            this.mKey = mKey;
        }

        public List<BeanHabilitation> getmValue() {
            return mValue;
        }

        public void setmValue(List<BeanHabilitation> mValue) {
            this.mValue = mValue;
        }

 public HabilitationInterprete(){

    }

    public HabilitationInterprete(String p_mKey, List<BeanHabilitation> p_mValue){
        this.mKey = p_mKey;
        this.mValue = p_mValue;
    }

And I modify my class InfoSecuriteBean

我修改了我的课程 InfoSecuriteBean

I changed this :

我改变了这个:

 @SerializedName("HabilitationAD")
    private Map<String,List<HabilitationBean>> mHabilitationAD = new HashMap<String, List<HabilitationBean>>();
    @SerializedName("HabilitationInterprete")
    private Map<String,List<HabilitationBean>> mHabilitationInterprete = new HashMap<String, List<HabilitationBean>>();

by this :

这样 :

@SerializedName("HabilitationAD")
    private List<HabilitationAD> habilitationAD;
    @SerializedName("HabilitationInterprete")
    private List<HabilitationInterprete> habilitationInterprete;

Now all work great ! Hope this solution will help !

现在一切都很好!希望这个解决方案会有所帮助!

回答by Mehdi

the error you're getting is pretty standard. Gson cannot deserialize nested objects. Gotta write your own adapters.

你得到的错误是非常标准的。Gson 不能反序列化嵌套对象。必须编写自己的适配器。

So you have to learn how to write a custom deserializer (very easy) and then register it when you create your gson object.

因此,您必须学习如何编写自定义反序列化器(非常简单),然后在创建 gson 对象时注册它。

Feel free to ask more questions.

随意提出更多问题。