Не понимаю как именно Retrofit парсит json с GSON и как с этим работать?

Вот что я нагуглил про получению json данных по api(немного псевдокод)

//тут как-бы ясно
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://site/api")
            .addConverterFactory(GsonConverterFactory.create())
            .build();
    //в api уже реализованный retrofit-ом метод из интерфеса
    DataInterface api = retrofit.create(DataInterface.class);

    //не совсем понял
    Call<List<MyModel>> call = api.getData();

    //это ок. обработка данных в новом потоке
    call.enqueue(new Callback<List<MyModel>>() {
        @Override
        public void onResponse(Call<List<MyModel>> call, Response<List<MyModel>> response) {
            //если я правильно понял, тут приходит список объектов MyModel
            //уже заполненный данными??? каким образом?
        }

        @Override
        public void onFailure(Call<List<MyModel>> call, Throwable t) {
            //обработка ошибки
        }
    });

А вот и DataInterface

public interface DataInterface {
        @GET("apiUri")
        Call<List<MyModel>> getData();
    }

Насколько я понял MyModel это POJO, но в примерах этот объект имел только приватные свойства и геттеры. Тогда что приходит в onResponse?

Помогите пожалуйста понять всю эту магию и как с этим работать. Спасибо.
  • Вопрос задан
  • 254 просмотра
Пригласить эксперта
Ответы на вопрос 2
@snitron
Учуcь программировать на Android, IOS и Unity.
При созднии объекта Retrofit Вы добавили конвертер для десериализации приходящих данных (в данном случае Gson). Этот конвертер реализуется через GsonConverterFactory.
.addConverterFactory(GsonConverterFactory.create())

В интерфейсе API Вы указали тип приходящих данных, завёрнутый в объект вызова Retrofit (Call):

Call<List<MyModel>> getData();

В итоге в метод onResponse() придёт List уже распарсенных данных (MyModel). Именно конвертер, который вы указали (Gson), по приходу данных десереализовал их в объекты того типа, которого Вы указали в интерфейсе API.
Ответ написан
Комментировать
azerphoenix
@azerphoenix Куратор тега Java
Java Software Engineer
Здравствуйте!
Скидываю вам пример кода, в данном случае я использую Retrofit c Jackson (вместо GSON)

public interface LfkServerAPI {
    @GET("rest/categories/list")
    Call<List<CategoryDTO>> getAllCategories();
}


@Data
public class Category {
private Long categoryId;

    private String categoryName;

    private String categoryDescription;

}


@Getter
@Setter
public class CategoryDTO {

    private Long categoryId;

    private String categoryName;

    private String categoryDescription;

}


public class ApiClient {

    public static Retrofit retrofit = null;

    public static Retrofit getApiClient() {

        if (retrofit == null) {

            retrofit = new Retrofit.Builder()
                    .baseUrl(Constants.BASE_URL)
                    .addConverterFactory(JacksonConverterFactory.create())
                    .build();

        }
        return retrofit;

    }

}


Обратите внимание на этот участок кода:
LfkServerAPI lfkServerAPI = ApiClient.getApiClient().create(LfkServerAPI.class);
Call<List<CategoryDTO>> allCategoriesListCall = lfkServerAPI.getAllCategories();

allCategoriesListCall.enqueue(new Callback<List<CategoryDTO>>() {
    @Override
    public void onResponse(Call<List<CategoryDTO>> call, Response<List<CategoryDTO>> response) {

        if (!response.isSuccessful()) {
            Log.d(LOG, "Ответ сервера: " + response.code());
            return;
        }

        // Вызываем метод body() из полученного ответа, где будет наш pojo
        List<CategoryDTO> categoryDTOS = response.body();

        if (categoryDTOS != null) {

        	categoryDTOS.forEach(categoryDTO -> {
				Category category = new Category();	
                category.setCategoryId(categoryDTO.getCategoryId());
                category.setCategoryName(categoryDTO.getCategoryName());
                category.setCategoryDescription(categoryDTO.getCategoryDescription());
                category.save();
        	});

        }
    }

    @Override
    public void onFailure(Call<List<CategoryDTO>> call, Throwable throwable) {
        Log.d(LOG, throwable.getMessage());
    }
});
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы