为了账号安全,请及时绑定邮箱和手机立即绑定

预期进行BEGIN_OBJECT的改造,但进行了BEGIN_ARRAY的改造

/ 猿问

预期进行BEGIN_OBJECT的改造,但进行了BEGIN_ARRAY的改造

catspeake 2019-11-15 21:08:35

我是JSON解析的新手,我使用Square的Retrofit库,遇到了这个问题。


我正在尝试解析此JSON响应:


[

      {

        "id": 3,

        "username": "jezer",

        "regid": "oiqwueoiwqueoiwqueoiwq",

        "url": "http:\/\/192.168.63.175:3000\/users\/3.json"

      },

      {

        "id": 4,

        "username": "emulator",

        "regid": "qwoiuewqoiueoiwqueoq",

        "url": "http:\/\/192.168.63.175:3000\/users\/4.json"

      },

      {

        "id": 7,

        "username": "test",

        "regid": "ksadqowueqiaksj",

        "url": "http:\/\/192.168.63.175:3000\/users\/7.json"

      }

]

这是我的模型:


public class Contacts {


    public List<User> contacts;


}

...


public class User {


    String username;

    String regid;


    @Override

    public String toString(){

        return(username);

    }  


}

我的界面:


public interface ContactsInterface {


    @GET("/users.json")

    void contacts(Callback<Contacts> cb);


}

我的成功方法:


@Override

public void success(Contacts c, Response r) {

    List<String> names = new ArrayList<String>();

    for (int i = 0; i < c.contacts.size(); i++) {

        String name = c.contacts.get(i).toString();

        Log.d("Names", "" + name);

        names.add(name);

    }

    ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(this,

            android.R.layout.simple_spinner_item, names);

    mSentTo.setAdapter(spinnerAdapter);

}

当我将其用于成功方法时,会引发错误


预期为BEGIN_OBJECT,但在第1行column2处为BEGIN_ARRAY


怎么了


查看完整描述

3 回答

?
波斯汪

现在,您正在解析响应,就好像它是这样格式化的:


{

  "contacts": [

    { .. }

  ]

}

异常告诉您,您期望在根目录有一个对象,但实际数据实际上是一个数组。这意味着您需要将类型更改为数组。


最简单的方法是仅将列表用作回调中的直接类型:


@GET("/users.json")

void contacts(Callback<List<User>> cb);


查看完整回答
反对 回复 2019-11-15
?
汪汪一只猫

在您的界面中替换


@GET("/users.json")

void contacts(Callback<Contacts> cb);

通过此代码


@GET("/users.json")

void contacts(Callback<List<Contacts>> cb);


查看完整回答
反对 回复 2019-11-15
?
元芳怎么了

dependencies used :


compile 'com.squareup.retrofit2:retrofit:2.3.0'

compile 'com.squareup.retrofit2:converter-gson:2.3.0'

json响应可以是array response或,object response甚至可以是两者的组合。请参阅以下三种情况


Case 1 : Parsing a json array response (OP案)


这种情况适用于以下json responses形式[{...} ,{...}]


例如


[

  {

    "id": 3,

    "username": "jezer",

    "regid": "oiqwueoiwqueoiwqueoiwq",

    "url": "http:\/\/192.168.63.175:3000\/users\/3.json"

  },

  .

  .

]

首先为此数组创建一个模型类,或者只是转到jsonschema2pojo并自动生成如下所示的模型类


Contacts.java


public class Contacts {


@SerializedName("id")

@Expose

private Integer id;

@SerializedName("username")

@Expose

private String username;

@SerializedName("regid")

@Expose

private String regid;

@SerializedName("url")

@Expose

private String url;


public Integer getId() {

return id;

}


public void setId(Integer id) {

this.id = id;

}


public String getUsername() {

return username;

}


public void setUsername(String username) {

this.username = username;

}


public String getRegid() {

return regid;

}


public void setRegid(String regid) {

this.regid = regid;

}


public String getUrl() {

return url;

}


public void setUrl(String url) {

this.url = url;

}


}

ContactsInterface


在这种情况下,您应该返回如下对象列表


public interface ContactsInterface {

@GET("/users.json")

Call<List<Contacts>> getContacts();

}

然后retrofit2像下面这样拨打电话


Retrofit retrofit = new Retrofit.Builder()

            .baseUrl("baseurl_here")

            .addConverterFactory(GsonConverterFactory.create())

            .build();

    ContactsInterface request = retrofit.create(ContactsInterface.class);

    Call<List<Contacts>> call = request.getContacts();

    call.enqueue(new Callback<List<Contacts>>() {

        @Override

        public void onResponse(Call<List<Contacts>> call, Response<List<Contacts>> response) {

            Toast.makeText(MainActivity.this,response.body().toString(),Toast.LENGTH_SHORT).show();

        }


        @Override

        public void onFailure(Call<List<Contacts>> call, Throwable t) {

            Log.e("Error",t.getMessage());

        }

    });

response.body() 将为您提供对象列表


您还可以检查以下两种情况以供参考


Case 2 : Parsing a json object response


这种情况适用于格式为{..}的json响应


例如


{

"id": 3,

"username": "jezer",

"regid": "oiqwueoiwqueoiwqueoiwq",

"url": "http:\/\/192.168.63.175:3000\/users\/3.json"

}

在这里,我们与object上面的示例相同。因此,模型类将是相同的,但是像上面的示例一样,我们没有这些对象的数组-只有一个对象,因此我们不需要将其解析为列表。


因此,对于 object response


public interface ContactsInterface {

    @GET("/users.json")

    Call<Contacts> getContacts();

    }

然后retrofit2像下面这样拨打电话


Retrofit retrofit = new Retrofit.Builder()

            .baseUrl("baseurl_here")

            .addConverterFactory(GsonConverterFactory.create())

            .build();

    ContactsInterface request = retrofit.create(ContactsInterface.class);

    Call<Contacts> call = request.getContacts();

    call.enqueue(new Callback<Contacts>() {

        @Override

        public void onResponse(Call<Contacts> call, Response<Contacts> response) {

            Toast.makeText(MainActivity.this,response.body().toString(),Toast.LENGTH_SHORT).show();

        }


        @Override

        public void onFailure(Call<Contacts> call, Throwable t) {

            Log.e("Error",t.getMessage());

        }

    });

response.body() 会给你对象


您还可以在解析json对象响应时检查一个常见错误:“预期的begin_array但为begin_object”


Case 3 : Parsing a json array inside json object


这种情况适用于以下json responses形式{"array_name":[{...} ,{...}]}


例如


    {

    "contacts": 

         [

            {

             "id": 3,

             "username": "jezer",

             "regid": "oiqwueoiwqueoiwqueoiwq",

             "url": "http:\/\/192.168.63.175:3000\/users\/3.json"

            }

         ]

    }

您将需要两个模型类,因为我们有两个对象(数组外一个,数组内一个)。


ContactWrapper


public class ContactWrapper {


@SerializedName("contacts")

@Expose

private List<Contacts> contacts = null;


public List<Contacts> getContacts() {

return contacts;

}


public void setContacts(List<Contacts> contacts) {

this.contacts = contacts;

}


}

您可以将Contacts.java上面生成的用于列表对象(针对情况1生成)


因此,对于 object response


public interface ContactsInterface {

    @GET("/users.json")

    Call<ContactWrapper> getContacts();

    }

然后retrofit2像下面这样拨打电话


Retrofit retrofit = new Retrofit.Builder()

            .baseUrl("baseurl_here")

            .addConverterFactory(GsonConverterFactory.create())

            .build();

    ContactsInterface request = retrofit.create(ContactsInterface.class);

    Call<ContactWrapper> call = request.getContacts();

    call.enqueue(new Callback<ContactWrapper>() {

        @Override

        public void onResponse(Call<ContactWrapper> call, Response<ContactWrapper> response) {

            Toast.makeText(MainActivity.this,response.body().getContacts().toString(),Toast.LENGTH_SHORT).show();

        }


        @Override

        public void onFailure(Call<ContactWrapper> call, Throwable t) {

            Log.e("Error",t.getMessage());

        }

    });

在这里,与案例1的区别在于我们应该使用response.body().getContacts()而不是response.body()获取对象列表


查看完整回答
反对 回复 2019-11-15

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信