Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $

454
17 июля 2017, 14:32

Есть такой интерфейс:

BackendlessAPI.java

    String BASE_URL = "https://api.backendless.com/" + APP_ID + "/" + API_KEY +"/";
    String IMAGES_FOLDER = "shops_images";
    String IMAGES_URL = BASE_URL + "files/" + IMAGES_FOLDER + "/";
    @GET("data/Shop")
    Observable<Shop> listShops();

Делаю REST запрос вот так:

DataManager.java

@Override
public Observable<Shop> loadShopsFromWeb() {
    Log.d(DEFAULT_TAG, "Try to load from web");
    final IDatabaseHelper databaseHelper = DatabaseHelper.getInstance();
    BackendlessAPI backendlessAPI = backendlessRetrofit.create(BackendlessAPI.class);
    Observable<Shop> shopsList = backendlessAPI
            .listShops()
            .timeout(LOAD_SHOPS_TIMEOUT, TimeUnit.SECONDS)
            .subscribeOn(Schedulers.io())
            .map(shop -> {
                databaseHelper.cacheShop(shop);
                return shop;
            });
    return shopsList;
}

Ожидается примерно такой JSON в ответ на запрос:

[
    {
        "created": 1500137157543,
        "imageUrl": "pekarnya.png",
        "name": "Пекарня на Патриотов",
        "___class": "Shop",
        "coordinates": [
            {
                "lng": 60.673511,
                "city": "Yekaterinburg",
                "street": "Патриотов 70",
                "created": 1500111228678,
                "city_ru": "Екатеринбург",
                "___class": "ShopGeoPoint",
                "lat": 56.782548,
                "objectId": "75F88D38-F831-1828-FF44-7CA466868F00"
            }
        ],
        "description": "Хотите качественную и вкусную выпечку? Заказывай наисвежайшие булочки в \"Пекарне на Патриотов\"",
        "type": "Пекарня",
        "objectId": "C97EDFBC-04BB-D59A-FFE0-A45138B1ED00"
    }
]

А вот мои POJO

Shop.java

public class Shop extends RealmObject {
    public Shop() {
    }
    public Shop(RealmList<ShopGeoPoint> coordinates, String name, String objectId, String imageUrl,
                String description, String type) {
        this.coordinates = coordinates;
        this.name = name;
        this.objectId = objectId;
        this.imageUrl = imageUrl;
        this.description = description;
        this.type = type;
    }

    public RealmList<ShopGeoPoint> getCoordinates() {
        return  coordinates;
    }
    public void setCoordinates(RealmList<ShopGeoPoint> coordinates) {
        this.coordinates = coordinates;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getObjectId() {
        return objectId;
    }
    public void setObjectId(String objectId) {
        this.objectId = objectId;
    }
    public String getImageUrl() {
        return imageUrl;
    }
    public void setImageUrl(String imageUrl) {
        this.imageUrl = imageUrl;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }

    private RealmList<ShopGeoPoint> coordinates;
    @Required
    private String name;
    @Required
    @PrimaryKey
    private String objectId;
    private String description;
    @Required
    private String imageUrl;
    private String type;

}

ShopGeoPoint.java

public class ShopGeoPoint extends RealmObject {

    public ShopGeoPoint(double lat, double lng, String street, String objectId) {
        this.lat = lat;
        this.lng = lng;
        this.street = street;
        this.objectId = objectId;
    }

    public ShopGeoPoint() {
    }
    public double getLat() {
        return lat;
    }
    public void setLat(double lat) {
        this.lat = lat;
    }
    public double getLng() {
        return lng;
    }
    public void setLng(double lng) {
        this.lng = lng;
    }
    public String getObjectId() {
        return objectId;
    }
    public void setObjectId(String objectId) {
        this.objectId = objectId;
    }
    public String getStreet() {
        return street;
    }
    public void setStreet(String street) {
        this.street = street;
    }
    private double lat;
    private double lng;
    @Required
    private String street;
    @PrimaryKey
    private String objectId;

}

POJO кешируются вот так:

DatabaseManager.java

@Override
    public void cacheShop(final Shop shop) throws NullPointerException {
        if(realm == null){
            throw new NullPointerException("Realm didn't init. Use getInstance() to get DatabaseHelper");
        }
        Log.d(DEFAULT_TAG, "Shop is cached");
        realm.executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(Realm bgRealm) {
                bgRealm.copyToRealm(shop);
            }
        });
    }

Почему вылетает такой Exception? Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $

Answer 1

Дословно ошибка расшифровывается/переводится так:

Ожидалось начало объекта, но имеем начало массива, падаю.

Т.е. в JSON у вас массив объектов, а вы пытаетесь парсить весь ответ как один объект.

Вам надо просто указать, что вы ожидаете массив.

@GET("data/Shop")
Observable<List<Shop>> listShops();
READ ALSO
Что плохого в моем коде тестового задания на java?

Что плохого в моем коде тестового задания на java?

Задача тестового: привести примеры использования ООП Что подтянуть? Критикуйте пожоще

250
Как вывести время без сдвига временной зоны

Как вывести время без сдвига временной зоны

Как вывести время без сдвига по временной зоне?

220
Что такое Bootstrap?

Что такое Bootstrap?

Объясните понятным языком, что это такое?

557
изменить стиль другого элемента React JS

изменить стиль другого элемента React JS

Мне нужно изменить цвет блока с классом "strip" при клике на radio как это сделать ?

547