如何使用 gson/retrofit 获取对象数组?

Posted

技术标签:

【中文标题】如何使用 gson/retrofit 获取对象数组?【英文标题】:How to get array of objects with gson/retrofit? 【发布时间】:2016-04-09 22:46:18 【问题描述】:

我之前用过gson自动转换成pojo的。

但现在我尝试使用改造将 api 结果转换为对象。

只要 json 有命名的对象数组,这没问题:

例如:


    items:[
        "name":"foo",
        "name":"bar"
    ]


public class AnItem 
    String name;


public class MyItems 
    List<AnItem> items;


public interface MyApi 
    @GET("/itemlist")
    Call<MyItems> loadItems();


public boolean onOptionsItemSelected(MenuItem item) 
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://someurl.com/api")
            .addConverterFactory(GsonConverterFactory.create())
            .build();
    MyApi myApi = retrofit.create(MyApi.class);
    Call<MyApi> call = myApi.loadItems();
    call.enqueue(this);
    return true;


@Override
public void onResponse(Response<MyItems> response, Retrofit retrofit) 
    ArrayAdapter<AnItem> adapter = (ArrayAdapter<AnItem>) getListAdapter();
    adapter.clear();
    adapter.addAll(response.body().items);

这将自动起作用。

但是如果json数组没有命名怎么办呢?

例如:

[
    "name":"foo",
    "name":"bar"
]

我知道在不使用带有 parsejson 的改造和迭代数组来获取我的对象时该怎么做,但我不能那样做,因为这部分是通过改造和 gson 自动完成的。

我真的被这个问题困住了一段时间,任何指针都将不胜感激..

更新:

below are the parts i have changed MyItems to List<AnItem>:



public class AllTemplatesRetroActivity extends ListActivity implements Callback<List<AnItem>> 

protected void onCreate(Bundle savedInstanceState) 

    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
    requestWindowFeature(Window.FEATURE_PROGRESS);
    ArrayAdapter<AnItem> arrayAdapter =
            new ArrayAdapter<AnItem>(this,
                    android.R.layout.simple_list_item_1,
                    android.R.id.text1,
                    new ArrayList<AnItem>());
    setListAdapter(arrayAdapter);


@Override
public boolean onOptionsItemSelected(MenuItem item) 
    Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://someurl.com/api")
        .addConverterFactory(GsonConverterFactory.create())
        .build();

    MyApi myApi = retrofit.create(MyApi.class);

    Call<List<AnItem>> call = myApi.loadItems();
    call.enqueue(this);
    return true;


@Override
public void onResponse(Response<List<AnItem>> response, Retrofit retrofit) 
    ArrayAdapter<AnItem> adapter = (ArrayAdapter<AnItem>) getListAdapter();
    adapter.clear();
    Log.i("##MYLOG###", "## response:"+ response.message());
    adapter.addAll(response.body());

【问题讨论】:

您可以通过将 Call 更改为 Call> 来处理最后一个 json 好的,我改了,但还有一个问题,要做什么:adapter.addAll(response.body().items);如果我将其更改为:adapter.addAll(response.body());我得到“java.lang.NullPointerException:尝试在空对象引用上调用接口方法'java.lang.Object [] java.util.Collection.toArray()'” 您可能还没有得到正确的 json 转换。您能否更新您的问题更改并检查您在 response.body() 中的内容? 实际上我更新的代码进入了 onFailure 块并显示消息:“预期 BEGIN_ARRAY 但在第 1 行第 1 列路径 $ 字符串”不知道这甚至意味着什么。 这意味着您的响应 json 格式不是 [ "name":"foo", "name":"bar"]。现在尝试将 Response> 更改为没有类型的 Response 以查看您得到的 json。如果你想尝试记录,试试这个***.com/a/33256827/2956135我想你可以看到更详细的回复。 【参考方案1】:

像这样处理 json 响应:

[
    "name":"foo",
    "name":"bar"
]

使用调用>


在Retrofit2中,HttpUrl.resolve()用于解析baseUrl和注解路径。

由于其工作原理,

这行得通:

.baseUrl("http://someurl.com")

@GET("/api/itemlist")    --> resolved to http://someurl.com/api/itemlist

或者这行得通

.baseUrl("http://someurl.com/api/")

@GET("itemlist")    --->  resolved to http://someurl.com/api/itemlist

但是,这行不通

.baseUrl("http://someurl.com/api")

 @GET("/itemlist")   ---> resolved to http://someurl.com/itemlist

【讨论】:

以上是关于如何使用 gson/retrofit 获取对象数组?的主要内容,如果未能解决你的问题,请参考以下文章

android之Retrofit使用

Android - GSon + RetroFit 中的继承和抽象类

RxAndroid+RxJava+Gson+retrofit+okhttp初步搭建android网络请求框架

如何在 aar 库中指定依赖项?

如何获取数组里对象的某个值

Javascript:如何使用字符串数组获取对象属性? [复制]