英文:
Using Zomato Api with Retrofit
问题
我正在尝试使用 Retrofit 从 Zomato API 检索餐厅列表,但我只得到空响应,而且我找不到我做错了什么。我已经尝试过将 @Header 更改为 @Query,并将响应类型从 ApiResponse 更改为 List<Restaurant>,但问题仍然存在。
以下是调用 ZomatoApi 的 /search 端点的响应示例:
"results_found": 4072,
"results_start": 0,
"results_shown": 1,
"restaurants": [
  {
    "restaurant": {
      "R": {
        "has_menu_status": {
          "delivery": -1,
          "takeaway": -1
        },
        "res_id": 17836294,
        "is_grocery_store": false
      },
      "apikey": "75be9f9e2239fe637bf9cb1b46979d91",
      "id": "17836294",
      "name": "Cervejaria Meia Banana",
      "url": "https://www.zomato.com/porto/cervejaria-meia-banana-coimbrões?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1",
      "location": {
        "address": "Avenida do Infante Dom Henrique, 178, Coimbrões, Vila Nova de Gaia",
        "locality": "Coimbrões",
        "city": "Porto",
        "city_id": 311,
        "latitude": "41.1213507499",
        "longitude": "-8.6152520031",
        "zipcode": "",
        "country_id": 164,
        "locality_verbose": "Coimbrões, Porto"
      },
      // 其他属性...
    }
  }
]
Api 接口:
public interface ZomatoApi {
    @GET("search")
    Call<ApiResponse> getNearbyRestaurants(
        @Query("lat") double lat,
        @Query("lon") double lon,
        @Query("count") int count,
        @Query("radius") double radius,
        @Header("api_key") String apiKey
    );
}
ApiResponse 类:
public class ApiResponse {
    private String results_found;
    private String results_start;
    private String results_shown;
    private List<Restaurant> restaurants;
    // 构造函数和其他方法...
}
Restaurant 类:
public class Restaurant {
    private String id;
    private String name;
    Location location;
    // 构造函数和其他方法...
}
Location 类:
public class Location {
    private String address;
    private String latitude;
    private String longitude;
    // 构造函数和其他方法...
}
你的代码片段还包括了一个用于发起 API 调用的 Fragment,在其中使用 Retrofit 调用了 Zomato API 的 /search 端点,并处理了响应。
英文:
I am trying to retrieve a list of restaurants from Zomato Api using RetroFit but I am only getting null responses and I can´t find what I did wrong.I already tried to change @Header to @Query and changing the response type from ApiResponse to List<Restaurant> but the problem persists.
This is an example of the response of a call to the /search endpoint of ZomatoApi
"results_found": 4072,
  "results_start": 0,
  "results_shown": 1,
  "restaurants": [
    {
      "restaurant": {
        "R": {
          "has_menu_status": {
            "delivery": -1,
            "takeaway": -1
          },
          "res_id": 17836294,
          "is_grocery_store": false
        },
        "apikey": "75be9f9e2239fe637bf9cb1b46979d91",
        "id": "17836294",
        "name": "Cervejaria Meia Banana",
        "url": "https://www.zomato.com/porto/cervejaria-meia-banana-coimbrões?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1",
        "location": {
          "address": "Avenida do Infante Dom Henrique, 178, Coimbrões, Vila Nova de Gaia",
          "locality": "Coimbrões",
          "city": "Porto",
          "city_id": 311,
          "latitude": "41.1213507499",
          "longitude": "-8.6152520031",
          "zipcode": "",
          "country_id": 164,
          "locality_verbose": "Coimbrões, Porto"
        },
        "switch_to_order_menu": 0,
        "cuisines": "Portuguese, Finger Food, Petiscos",
        "timings": "08:00 to 24:00 (Mon, Tue, Wed, Thu, Sun), 08:00 to 02:00 (Fri-Sat)",
        "average_cost_for_two": 35,
        "price_range": 3,
        "currency": "€",
        "highlights": [
          "Lunch",
          "Debit Card",
          "Breakfast",
          "Dinner",
          "Indoor Seating",
          "Wine",
          "Fullbar",
          "Beer"
        ],
        "offers": [],
        "opentable_support": 0,
        "is_zomato_book_res": 0,
        "mezzo_provider": "OTHER",
        "is_book_form_web_view": 0,
        "book_form_web_view_url": "",
        "book_again_url": "",
        "thumb": "https://b.zmtcdn.com/data/res_imagery/17836294_RESTAURANT_2d9d944dfca0415414fdfeca7522c396.jpg?fit=around%7C200%3A200&crop=200%3A200%3B%2A%2C%2A",
        "user_rating": {
          "aggregate_rating": "3.4",
          "rating_text": "Average",
          "rating_color": "CDD614",
          "rating_obj": {
            "title": {
              "text": "3.4"
            },
            "bg_color": {
              "type": "lime",
              "tint": "500"
            }
          },
          "votes": 24
        },
        "all_reviews_count": 10,
        "photos_url": "https://www.zomato.com/porto/cervejaria-meia-banana-coimbrões/photos?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1#tabtop",
        "photo_count": 30,
        "menu_url": "https://www.zomato.com/porto/cervejaria-meia-banana-coimbrões/menu?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1&openSwipeBox=menu&showMinimal=1#tabtop",
        "featured_image": "https://b.zmtcdn.com/data/res_imagery/17836294_RESTAURANT_2d9d944dfca0415414fdfeca7522c396.jpg",
        "has_online_delivery": 0,
        "is_delivering_now": 0,
        "store_type": "",
        "include_bogo_offers": true,
        "deeplink": "zomato://restaurant/17836294",
        "is_table_reservation_supported": 0,
        "has_table_booking": 0,
        "events_url": "https://www.zomato.com/porto/cervejaria-meia-banana-coimbrões/events#tabtop?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1",
        "phone_numbers": "22 3792953",
        "all_reviews": {
          "reviews": [
            {
              "review": []
            },
            {
              "review": []
            },
            {
              "review": []
            },
            {
              "review": []
            },
            {
              "review": []
            }
          ]
        },
        "establishment": [
          "Casual Dining"
        ],
        "establishment_types": []
      }
    }
  ]
}
Api Interface
public interface ZomatoApi {
    @GET("search")
    Call<ApiResponse> getNearbyRestaurants(@Query("lat") double lat, @Query("lon") double lon,
                        @Query("count") int count,@Query("radius") double radius, @Header("api_key") String apiKey);
}
ApiResponse Class
package com.cmuteam.app;
import java.util.List;
public class ApiResponse {
        private String results_found;
        private String  results_start;
        private String results_shown;
        private List<Restaurant> restaurants;
    public ApiResponse(String results_found, String results_start, String results_shown, List<Restaurant> restaurants) {
        this.results_found = results_found;
        this.results_start = results_start;
        this.results_shown = results_shown;
        this.restaurants = restaurants;
    }
    public String getResults_found() {
        return results_found;
    }
    public String getResults_start() {
        return results_start;
    }
    public String getResults_shown() {
        return results_shown;
    }
    public List<Restaurant> getRestaurants() {
        return restaurants;
    }
}
Restaurant Class
package com.cmuteam.app;
public class Restaurant {
    private String id;
    private String name;
    Location location;
    public String getId() {
        return id;
    }
    public String getName() {
        return name;
    }
    public Location getLocation() {
        return location;
    }
    public Restaurant(String id, String name, Location location) {
        this.id = id;
        this.name = name;
        this.location = location;
    }
}
Location Class
public class Location {
    private String address;
    private String latitude;
    private String longitude;
    public Location(String address, String latitude, String longitude) {
        this.address = address;
        this.latitude = latitude;
        this.longitude = longitude;
    }
    public String getAddress() {
        return address;
    }
    public String getLatitude() {
        return latitude;
    }
    public String getLongitude() {
        return longitude;
    }
Fragment where i make the Api call
 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = getContext();
        mAuth = FirebaseAuth.getInstance();
        restaurantsList= new ArrayList<>(50);
        getApi().getNearbyRestaurants(41.12108,-8.615718100000002,20,10000,"75be9f9e2239fe637bf9cb1b46979d91")
                .enqueue(new Callback<ApiResponse>() {
                    @Override
                    public void onResponse(Call<ApiResponse> call, Response<ApiResponse> response) {
                        List<Restaurant> restaurants=response.body().getRestaurants();
                        mAdapter = new RestaurantAdapter(context, restaurantsList);
                        RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(context, DividerItemDecoration.VERTICAL);
                        mRecyclerView.addItemDecoration(itemDecoration);
                        for (int i = 0; i < restaurants.size(); i++) {
                            restaurantsList.add(new Restaurant(restaurants.get(i).getId(),restaurants.get(i).getName(),restaurants.get(i).getLocation()));
                            mAdapter.notifyItemInserted(i);
                        }
                    }
                    @Override
                    public void onFailure(Call<ApiResponse> call, Throwable t) {
                        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
                        builder.setMessage("Couldn´t find any nearby restaurants");
                        AlertDialog mDialog = builder.create();
                        mDialog.show();
                    }
                });
    }
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View mContentView = inflater.inflate(R.layout.poi_list, container,false);
        mRecyclerView = mContentView.findViewById(R.id.recycler_view);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(mContentView.getContext()));
        mRecyclerView.setAdapter(mAdapter);
        return mContentView;
    }
    private Retrofit getRetrofit(){
        return new Retrofit.Builder()
                .baseUrl("https://developers.zomato.com/api/v2.1/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
    private ZomatoApi getApi(){
        return  getRetrofit().create(ZomatoApi.class);
    }
答案1
得分: 0
授权头部称为"user-key",而不是在zomato文档中提到的"api_key"。
英文:
The authorization header is called "user-key" not "api_key" as mentioned in zomato docs.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论