I have this JSON body:
[
{
"id": 0,
"field1": "10",
"field2": "22"
},
{
"id": 1,
"field1": "11",
"field2": "23"
}
]
My pojoItem
:
@AutoValue
public abstract class PojoItem{
@SerializedName("field1")
public abstract String field1();
@SerializedName("id")
public abstract int id();
@SerializedName("field2")
public abstract String field2();
}
And my pojoItemList
:
@AutoValue
public abstract class PojoItemList{
public abstract List< PojoItem > itemList();
public static TypeAdapter<PojoItemList> typeAdapter(Gson gson) {
return new AutoValue_PojoItemList.GsonTypeAdapter(gson);
}
}
I have AutoValueGsonFactory
:
@GsonTypeAdapterFactory
public abstract class AutoValueGsonFactory implements TypeAdapterFactory {
// Static factory method to access the package
// private generated implementation
public static TypeAdapterFactory create() {
return new AutoValueGson_AutoValueGsonFactory();
}
}
I'm using Retrofit with RxJava. I got this exception:
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY
How can I setup my POJO to read JSON as an array of objects not as collection?
I could make it work by the end with/without RxJava Here are two ways:
To make it clear I will provide API and complete Retrofit code used to achieve that goal:
AppApi:
public interface AppApi {
@GET("path/path")
Observable<List<PojoItem>> getItemsbyRxJava();
@GET("path/path")
Call<List<PojoItem>> getItemsbyRetrofit();
}
Solution with RxJava:
GsonConverterFactory gsonConverterFactory = GsonConverterFactory.create(new GsonBuilder().registerTypeAdapterFactory(AutoValueGsonFactory.create()).create());
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
Retrofit retrofitClient = new Retrofit.Builder()
.baseUrl("http://[domain]/path/")
.addConverterFactory(gsonConverterFactory)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(httpClient.build())
.build();
AppApi appApi = retrofitClient.create(AppApi.class);
appApi.getItemsbyRxJava()
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<List<PojoItem>>() {
@Override
public void onCompleted() {
Log.d(TAG, "completed");
}
@Override
public void onError(Throwable e) {
Log.e(TAG, e.getMessage());
}
@Override
public void onNext(List<PojoItem> list) {
for (PojoItem pojoItem : list) {
Log.d(TAG, pojoItem.field1() + "," + pojoItem.field2());
}
}
});
Solution with Retrofit only:
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
Retrofit retrofitClient = new Retrofit.Builder()
.baseUrl("http://[domain]/path/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(httpClient.build())
.build();
AppApi appApi = retrofitClient.create(AppApi.class);
Call<List<PojoItem>> call = appApi.getItemsbyRetrofit();
call.enqueue(new Callback<List<PojoItem>>() {
@Override
public void onResponse(Call<List<PojoItem>> call, Response<List<PojoItem>> response) {
for (PojoItem pojoItem : response.body()) {
Log.d(TAG, pojoItem.field1() + "," + pojoItem.field2());
}
}
@Override
public void onFailure(Call<List<PojoItem>> call, Throwable t) {
Log.e(TAG, t.getMessage());
}
});
I hope that would be helpful to someone
Good luck,'.