#java #android #json #gson #retrofit2
#java #Android #json #gson #retrofit2
Вопрос:
Учитывая следующий ответ JSON:
{
"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
}
]
}
]
}
Я использую это в сочетании с Retrofit2. Мой класс обслуживания выглядит примерно так:
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);
}
и я на самом деле занимаюсь получением этих данных в задаче rx:
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.");
})
);
Как мне сообщить моему GsonConverterFactory начать синтаксический "doc"
анализ массива? На самом деле меня не волнует первое "status"
поле.
Я спрашиваю, потому что получаю следующую ошибку: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
. Я почти уверен, что это потому, что GSON пытается проанализировать первый элемент и не попадает в "doc"
массив.
Я ценю любую помощь!
Редактировать
Вот HavocAPI (сейчас меня беспокоит только getAllTasks()
то, как он работает).
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);
}
Комментарии:
1. Вам нужно показать нам свой
HavocAPI
интерфейс и модель возвращаемого типа для вашего API getAllTasks. Проблема, скорее всего, связана с моделью.2. Приношу свои извинения. Я не думал, что в этом будет необходимость. Я обновил ОП.
Ответ №1:
Возвращаемый тип для getAllTasks()
метода неверен. Вам нужно создать новую модель, представляющую фактический формат ответа, а затем получить доступ к списку задач через нее.
class GetTasksResponse {
bool status;
@SerializedName("doc")
List<Task> tasks;
public List<Task> getTasks() {
return tasks;
}
}
Комментарии:
1. Итак, затем в моем API я бы сделал что-то вроде:
Observable<GetTasksResponse> getAllTasks()
?