Класс модели для Zomato Android API

Здравствуйте, я пытаюсь разработать приложение, для которого мне нужен список ресторанов в определенном городе. Я пытаюсь использовать API Zomato для того же. Из документации по адресу https://developers.zomato.com/documentation я понял, что метод /geocode быть наиболее подходящим для того, что мне нужно. Пример ответа на это выглядит следующим образом:

{"location": {
"entity_type": "",
"entity_id": 0,
"title": "Al Quoz",
"latitude": "25.1345620000",
"longitude": "55.2365110000",
"city_id": 51,
"city_name": "Dubai",
"country_id": 214,
"country_name": "UAE"
},
 "popularity": {
"popularity": "2.02",
"nightlife_index": "0.00",
"nearby_res": [
  "18274882",
  "206670",
  "18279664",
  "18264893",
  "208532",
  "210411",
  "207764",
  "18279641",
  "203695"
],
"top_cuisines": [
  "Indian",
  "Chinese",
  "Middle Eastern",
  "Pakistani",
  "Arabian"
],
"popularity_res": "100",
"nightlife_res": "10",
"subzone": "Al Quoz",
"subzone_id": 51301,
"city": "Dubai"
 },
 "link": "https://www.zomato.com/dubai/al-quoz-restaurants?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1",
  "nearby_restaurants": {
"1": {
  "restaurant": {
    "R": {
      "res_id": 18274882
    },
    "apikey": "--",
    "id": "18274882",
    "name": "Ice Lab",
    "url": "https://www.zomato.com/dubai/ice-lab-al-quoz?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1",
    "location": {
      "address": "Behind Al Quoz Pond Park, Meydan Road, Al Quoz, Dubai",
      "locality": "Al Quoz",
      "city": "Dubai",
      "city_id": 51,
      "latitude": "0.0000000000",
      "longitude": "0.0000000000",
      "zipcode": "",
      "country_id": 214
    },
    "cuisines": "Ice Cream",
    "average_cost_for_two": 85,
    "price_range": 2,
    "currency": "AED",
    "offers": [],
    "thumb": "https://b.zmtcdn.com/images/res_avatar_120_1x_new.png",
    "user_rating": {
      "aggregate_rating": "3.7",
      "rating_text": "Very Good",
      "rating_color": "5BA829",
      "votes": "30"
    },
    "photos_url": "https://www.zomato.com/dubai/ice-lab-al-quoz/photos#tabtop?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1",
    "menu_url": "https://www.zomato.com/dubai/ice-lab-al-quoz/menu#tabtop?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1",
    "featured_image": "",
    "has_online_delivery": 0,
    "is_delivering_now": 0,
    "deeplink": "zomato://r/18274882",
    "events_url": "https://www.zomato.com/dubai/ice-lab-al-quoz/events#tabtop?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1"
  }
},
"2": {
  "restaurant": {
    "R": {
      "res_id": 206670
    },
    "apikey": "--",
    "id": "206670",
    "name": "Dubai Amaravathi",
    "url": "https://www.zomato.com/dubai/dubai-amaravathi-al-quoz?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1",
    "location": {
      "address": "Behind Old Grand Mall, Al Quoz, Dubai",
      "locality": "Al Quoz",
      "city": "Dubai",
      "city_id": 51,
      "latitude": "25.1465708500",
      "longitude": "55.2434410527",
      "zipcode": "",
      "country_id": 214
    },
    "cuisines": "Indian, North Indian, South Indian, Chinese",
    "average_cost_for_two": 50,
    "price_range": 2,
    "currency": "AED",
    "offers": [],
    "thumb": "https://b.zmtcdn.com/data/pictures/0/206670/a6140b8b6205d23c5fa123c7faeb7857_res_featured_thumb.png",
    "user_rating": {
      "aggregate_rating": "3.2",
      "rating_text": "Good",
      "rating_color": "9ACD32",
      "votes": "40"
    },
    "photos_url": "https://www.zomato.com/dubai/dubai-amaravathi-al-quoz/photos#tabtop?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1",
    "menu_url": "https://www.zomato.com/dubai/dubai-amaravathi-al-quoz/menu#tabtop?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1",
    "featured_image": "https://b.zmtcdn.com/data/pictures/0/206670/a6140b8b6205d23c5fa123c7faeb7857_featured_v2.png",
    "has_online_delivery": 1,
    "is_delivering_now": 1,
    "deeplink": "zomato://r/206670",
    "order_url": "https://www.zomato.com/dubai/dubai-amaravathi-al-quoz/order?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1",
    "order_deeplink": "",
    "events_url": "https://www.zomato.com/dubai/dubai-amaravathi-al-quoz/events#tabtop?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1"
  }
}
}
}
}

Я пытаюсь создать класс модели Android для того же, чтобы проанализировать ответ с помощью GSON. Моя цель - просто добавить объекты "ресторан" в список, чтобы я мог передать их адаптеру представления карты.

На данный момент моя модель выглядит так -

public class RestaurantsZomato {

public LocationDetails location;
public Popularity popularity;
public String link;
public NearbyRestaurants nearby_restaurants;

public static class LocationDetails {
    public String entity_type;
    public int entity_id;
    public String title;
    public String latitude;
    public String longitude;
    public int city_id;
    public String city_name;
    public int country_id;
    public String country_name;
}

public static class Popularity {
    public String popularity;
    public String nightlife_index;
    public List<String> nearby_res;
    public List<String> top_cuisines;
    public String popularity_res;
    public String nightlife_res;
    public String subzone;
    public int subzone_id;
    public String city;
}

public static class NearbyRestaurants {

    public RestaurantDetails restaurant;
}

public class RestaurantDetails {

public Rest R;
public String apikey;
public String id;
public String name;
public String url;
public LocationDetails location;
public String cuisines;
public String average_cost_for_two;
public String price_range;
public String currency;
public List<String> offers;
public String thumb;
public UserRating user_rating;
public String photos_url;
public String menu_url;
public String featured_image;
public String has_online_delivery;
public String is_delivering_now;
public String deeplink;
public String events_url;
public String all_reviews_count;
public String photo_count;
public String phone_numbers;

public LocationDetails getLocation(){
    return location;
}

public static class LocationDetails {
    public String address;
    public String locality;
    public String city;
    public String latitude;
    public String longitude;
    public String zipcode;
    public String country_id;

    public String getAddress() {
        return address;
    }
}

  public static class UserRating {
    public static String aggregate_rating;
    public String rating_text;
    public String rating_color;
    public String votes;
}

public static class Rest {
    public float res_id;
}

}

И в моем Фрагменте после веб-сервиса я разбираю его так:

Ion.getDefault(getActivity()).configure().setLogging(getString(R.string.app_name), Log.DEBUG);
            Ion.with(getActivity())
                    .load("https://developers.zomato.com/api/v2.1/geocode?lat=25.12819&lon=55.22724")
                    .setHeader("user-key","my-user-key")
                    .asJsonObject()
                    .setCallback(new FutureCallback<JsonObject>() {
                        @Override
                        public void onCompleted(Exception e, JsonObject result) {

                                Log.d("FoodFragment", result.toString());
                                RestaurantsZomato r = (RestaurantsZomato) new Gson().fromJson(result.toString(), new TypeToken<RestaurantsZomato>(){}.getType());
                                JsonObject nearby_restaurants = result.get("nearby_restaurants").getAsJsonObject();
                                Log.d("RestDetails",nearby_restaurants.toString());

                                JsonObject rest = nearby_restaurants.get("1").getAsJsonObject();
                                Log.d("RestZomato", rest.toString());
                                JsonObject details = rest.get("restaurant").getAsJsonObject();
                                Log.d("RestZomato", details.toString());
                                RestaurantDetails ad = new Gson().fromJson(details, new TypeToken<RestaurantDetails>(){}.getType());

                                Set<Map.Entry<String, JsonElement>> objects =  nearby_restaurants.entrySet();
                                for (Map.Entry<String, JsonElement> entry : objects) {
                                    System.out.println(entry.getKey() + "/" + entry.getValue());
                                    if (entry.getValue() != null) {
                                        RestaurantDetails rd = new Gson().fromJson(entry.getValue(), RestaurantDetails.class);
                                        Log.d("simpletest",rd.getLocation().getAddress());
                                        sTrips.add(rd);
                                    }
                                }

                               adapter = new RestaurantAdapter(sTrips);
                                recyclerView.setAdapter(adapter);
                        }
                    });
        }

где sTrips — объект типа RestaurantDetails. Я получаю исключение в строке sTrips.add(rd), так как rd имеет значение null. Однако я не могу понять, что я делаю неправильно. Пожалуйста помоги!

Трассировка стека выглядит следующим образом:

FATAL EXCEPTION: main
java.lang.NullPointerException
at majorproject.amity.smarttourist.fragments.FoodFragment$2.onCompleted(FoodFragment.java:161)
at majorproject.amity.smarttourist.fragments.FoodFragment$2.onCompleted(FoodFragment.java:131)
at com.koushikdutta.async.future.SimpleFuture.handleCallbackUnlocked(SimpleFuture.java:107)
at com.koushikdutta.async.future.SimpleFuture.setComplete(SimpleFuture.java:141)
at com.koushikdutta.async.future.SimpleFuture.setComplete(SimpleFuture.java:128)
at com.koushikdutta.ion.IonRequestBuilder$1.run(IonRequestBuilder.java:246)
at com.koushikdutta.async.AsyncServer$RunnableWrapper.run(AsyncServer.java:57)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5419)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
at dalvik.system.NativeStart.main(Native Method)

ОБНОВЛЕНИЕ Ошибка в строке Log.d("самый простой",rd.getLocation().getAddress());

Я отладил его и обнаружил, что значение rd действительно равно нулю. Это изображение, показывающее отладку


person Vijayalakshmi Vedantham    schedule 07.05.2016    source источник
comment
вам нужно отредактировать свой вопрос, чтобы включить трассировку стека. похоже, вы описываете NullPointerException, но я скептически отношусь к этому, потому что rd имеет значение null в sTrips.add(rd) , потому что это всего лишь строка перед использованием этого объекта. вы не показали нам, где инициализируется sTrips, вы уверены, что объект не нулевой?   -  person trooper    schedule 07.05.2016
comment
@trooper я добавил трассировку стека и результат отладки. пожалуйста помоги!   -  person Vijayalakshmi Vedantham    schedule 08.05.2016
comment
hrm, поэтому на вашем снимке экрана видно, что rd фактически назначено (не ноль), но getLocation возвращает ноль. Я не совсем уверен, что здесь происходит - извините, я действительно не очень помог, но заголовок stackoverflow.com/questions/22244598/ и stackoverflow.com/questions/5656123/ выглядят очень похоже. Я предполагаю, что с вашим POJO что-то не так.   -  person trooper    schedule 08.05.2016


Ответы (1)


На самом деле вы читаете значения "1"/"2", в то время как вы предполагаете читать значение restaurant внутри цикла for. проверьте ответ.

    JsonObject rest = nearby_restaurants.get("1").getAsJsonObject();
    // Log.d("RestZomato", rest.toString());

    JsonObject details = rest.get("restaurant").getAsJsonObject();
    // Log.d("RestZomato", details.toString());
    RestaurantDetails ad = new Gson().fromJson(details, new TypeToken<RestaurantDetails>() {}.getType());

    Set<Map.Entry<String, JsonElement>> objects = nearby_restaurants.entrySet();

    for (Map.Entry<String, JsonElement> entry : objects) {
        System.out.println(entry.getKey() + "/" + entry.getValue());
        //entry.getValue() is the value of key "1"
        JsonObject ob=entry.getValue().getAsJsonObject();
        //you was reading value of "1" while you are suppose to read value of "restaurant"

        //get value from "restaurant" object

        if (ob != null) {
            //RestaurantDetails is created to read value of "restaurant"
            String restaurant=ob.get("restaurant").getAsJsonObject().toString(); 
            RestaurantDetails rd = new Gson().fromJson(restaurant, RestaurantDetails.class);
            System.out.println("Name "+rd.name);
            System.out.println(rd.getLocation().address);
        }
    }
person Bharatesh    schedule 11.05.2016