Использование динамических клавиш с GSON / Retrofit 2? - PullRequest
0 голосов
/ 06 мая 2019

У меня есть API, который возвращает следующую схему для всех запросов к коллекциям моделей:

{
    item_count: 83,
    items_per_page: 25,
    offset: 25,
    <Model>s: [
        { ... },
        { ... },
        { ... },
        ...
    ]
}

Например, если я сделаю запрос к /api/v1/customers, тогда этот JSON будет содержать customersключ.Если я сделаю запрос к /api/v1/products, тогда этот JSON будет содержать ключ products.

I с целью создания универсального класса PaginatedResponse<T> для обработки item_count, items_per_page и offset переменные вроде этого:

public class PaginatedResponse<T> {
    private int item_count;
    private int items_per_page;
    private int offset;
    private List<T> data;

    public PaginatedResponse<T>(int item_count, int items_per_page, int offset, List<T> data) {
        this.item_count = item_count;
        this.items_per_page = items_per_page;
        this.offset = offset;
        this.data = data;
    }

    public List<T> getData() {
        return this.data;
    }
}

Есть ли способ проанализировать этот JSON в моем PaginatedResponse POJO?

1 Ответ

1 голос
/ 07 мая 2019

Поскольку у вас есть разные ключи для списка моделей, <Model>s:, ИМХО, вам лучше использовать разные модели для каждого ответа.Вы должны удалить private List<T> data; из базовой модели ответа и переместить ее в дочернюю модель.

Я изменил ваш код и создал несколько примеров моделей для ваших products и customers.Ниже приведен подробный пример:

BasePaginatedResponse.java

public class BasePaginatedResponse {

    private int item_count;
    private int items_per_page;
    private int offset;

    public BasePaginatedResponse(
            int item_count, int items_per_page, int offset) {
        this.item_count = item_count;
        this.items_per_page = items_per_page;
        this.offset = offset;
    }

}

CustomersResponse.java

public class CustomersResponse extends BasePaginatedResponse {

    private final List<Customer> customers;

    public CustomersResponse(int item_count, int items_per_page, int offset, List<Customer> customers) {
        super(item_count, items_per_page, offset);
        this.customers = customers;
    }

    public List<Customer> getCustomers() {
        return customers;
    }

    public class Customer {
        private final String id, name;

        public Customer(String id, String name) {
            this.id = id;
            this.name = name;
        }

        public String getId() {
            return id;
        }

        public String getName() {
            return name;
        }
    }
}

ProductsResponse.java

public class ProductsResponse extends BasePaginatedResponse {

    private final List<Customer> products;

    public ProductsResponse(int item_count, int items_per_page, int offset, List<Customer> products) {
        super(item_count, items_per_page, offset);
        this.products = products;
    }

    public List<Customer> getProducts() {
        return products;
    }

    public class Customer {
        private final String id, name;

        public Customer(String id, String name) {
            this.id = id;
            this.name = name;
        }

        public String getId() {
            return id;
        }

        public String getName() {
            return name;
        }
    }
}

Здесь я создал 3 класса.1 базовый класс ответа (родительский) и 2 дочерних класса.Родительский класс содержит поля, общие для обоих дочерних классов.

Поскольку вы используете Retrofit, ваш ApiInterface должен быть примерно таким

interface ApiInterface{
    @GET("api/v1/customers")
    Call<CustomersResponse> getCustomers();

    @GET("api/v1/products")
    Call<ProductsResponse> getProducts();
}

Если вам нужно больше разъяснений, спросите меня в комментариях.

...