Заставить GsonConverterFactory анализировать определенные поля?

#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() ?