Nxt3 Nxt3 - 1 month ago 17
JSON Question

Get GsonConverterFactory to parse certain fields?

Given the following JSON response:

{
"status":true,
"doc":[
{
"_id":"9374",
"t_id":"5678",
"name":"Do calculus homework",
"description":"Finish all assigned homework from chapters 1 and 2",
"category":"test",
"indexInList":0,
"priority":3,
"dateDue":1477291500000,
"user":"def",
"status":"ARCHIVED",
"__v":0,
"subtasks":[
{
"name":"Finish Chapter 1 - Derivatives",
"isCompleted":false
},
{
"name":"Finish Chapter 1 - Integrals",
"isCompleted":false
},
{
"name":"Finish Chapter 2 - Graphing",
"isCompleted":false
}
]
},
{
"_id":"429808",
"t_id":"1234",
"name":"Write machine learning essay",
"description":"Write essay on Bayesian networks",
"category":"test",
"indexInList":1,
"priority":3,
"dateDue":1477291500000,
"user":"abc",
"status":"ARCHIVED",
"__v":0,
"subtasks":[
{
"name":"Write introduction",
"isCompleted":false
},
{
"name":"Write body",
"isCompleted":false
},
{
"name":"Write Conclusion",
"isCompleted":false
}
]
}
]
}


I'm using this in conjunction with Retrofit2. My Service class looks something like this:

private HavocService(String baseUrl) {
//So network calls are async
RxJavaCallAdapterFactory rxAdapter = RxJavaCallAdapterFactory.createWithScheduler(Schedulers.io());

HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();

final Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.client(client)
.addCallAdapterFactory(rxAdapter)
.addConverterFactory(GsonConverterFactory.create())
.build();

mHavocApi = retrofit.create(HavocAPI.class);
}


and I'm actually handling getting that data in an rx task:

rxHelper.manageSubscription(HavocService.getInstance().getHavocAPI().getAllTasks(userId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.compose(RxTiPresenterUtils.deliverLatestToView(this))
.subscribe(mListOfTasks -> {
this.mListOfTasks = mListOfTasks;
getView().setTaskList(mListOfTasks);
}, throwable -> {
LogUtil.e("Error with something.");
})
);


How do I tell my GSONConverterFactory to start parsing at the
"doc"
array? I don't really care about the first
"status"
field.

I ask because I'm getting the following error:
java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
. I'm pretty sure it's because GSON is trying to parse the first item and not getting to the
"doc"
array.

I appreciate any and all help!

Edit

Here is the HavocAPI (I'm only concerned about the
getAllTasks()
working right now.)


public interface HavocAPI {

/**
* Creates a new Task
*
* @return status of whether or not the transaction was successful and the task that was created
*/
@Headers({"Accept: application/json", "Content-Type: application/json"})
@POST("task/create/")
Observable<List<Object>> createNewTask();

/**
* Deletes a specified Task using the taskId
*
* @param taskID of the task
* @return status of transaction
*/
@Headers({"Accept: application/json", "Content-Type: application/json"})
@POST("task/delete/{task_id}/")
Observable<Boolean> deleteTask(@Path("task_id") String taskID);

/**
* Updates a Task
*
* @return status of whether or not the transaction was successful and the task that was updated
*/
@Headers({"Accept: application/json", "Content-Type: application/json"})
@POST("task/update/")
Observable<List<Object>> updateTask();

/**
* Gets all Tasks by a specified User
*
* @param userId of the user
* @return list of all Tasks from the specified User
*/
@Headers({"Accept: application/json", "Content-Type: application/json"})
@GET("task/read/{user_id}/")
Observable<List<Task>> getAllTasks(@Path("user_id") String userId);
}

Answer

The return type for the getAllTasks() method is incorrect. You need to create a new model representing the actual response format then access the task list through it.

class GetTasksResponse {
    bool status;
    @SerializedName("doc")
    List<Task> tasks;

    public List<Task> getTasks() {
        return tasks;
    }
}