如何使用Retrofit和Gson获取外键的字段?

时间:2016-05-29 12:49:41

标签: android json gson retrofit retrofit2

我有一个api端点,它为事件表输出这个json

{
    "name": "",
    "time": null,
    "event_pic_url": null,
    "description": "",
    "event_type": null,
    "invite_only": false,
    "free": false,
    "age_restriction": false,
    "ticket_price": null,
    "venue": null
}

场地字段是具有此格式的Venue表的外键。

{
    "name": "",
    "rating": null,
    "longitude": null,
    "latitude": null
}

获取事件列表后,我想将它们放在recyclerview上(我已经可以获取列表并知道如何使用适配器)但我不想显示场地的{id},我想要使用场地的{name}。我该怎么做呢?它与嵌套的json如何反序列化有关吗?

1 个答案:

答案 0 :(得分:1)

在所有评论之后,我会假设现在你有类似的东西:

{
  "name": "",
  "time": null,
  "event_pic_url": null,
  "description": "",
  "event_type": null,
  "invite_only": false,
  "free": false,
  "age_restriction": false,
  "ticket_price": null,
  "venue": {
     "name": "",
     "rating": null,
     "longitude": null,
     "latitude": null
  }
}

由于您正在使用Gson,因此您希望拥有以下型号

public class Venue {

  @SerializedName("name")
  @Expose
  private String name;
  @SerializedName("rating")
  @Expose
  private Integer rating;
  @SerializedName("longitude")
  @Expose
  private Double longitude;
  @SerializedName("latitude")
  @Expose
  private Double latitude;

  // ...
}

public class Event {

  @SerializedName("name")
  @Expose
  private String name;
  @SerializedName("time")
  @Expose
  private String time;
  @SerializedName("event_pic_url")
  @Expose
  private String eventPicUrl;
  @SerializedName("description")
  @Expose
  private String description;
  @SerializedName("event_type")
  @Expose
  private String eventType;
  @SerializedName("invite_only")
  @Expose
  private Boolean inviteOnly;
  @SerializedName("free")
  @Expose
  private Boolean free;
  @SerializedName("age_restriction")
  @Expose
  private Boolean ageRestriction;
  @SerializedName("ticket_price")
  @Expose
  private Double ticketPrice;
  @SerializedName("venue")
  @Expose
  private Venue venue;
  // ...
}

请注意,我在这里假设了一些数据类型,即latitudelongitude以及event_type。因为在json中他们是null我无法确定,但我想你可以从这个例子中理解。另外,请添加适当的getter和setter。

我希望你专注于venue部分。如你所见,我基本上正在重建"嵌套" json部分在Java对象中。只有它,Gsonretrofit将为您完成剩下的工作。这是怎么回事。需要注意的是 - 根据您的工作方式,这可能会有很大差异。我更喜欢rxjava,但我会在这里使用回调方法,因为它更容易解释。

改进 1.9 你可以这样做:

public interface EventService {
   @GET("/url/to/events/endpoint/")
   public void get(Callback<Event> callback);
}

如果一切顺利,在您的回调的success方法中,您将获得Event的实例,您可以访问Venue对象,前提是返回的json实际上是上面那个。

改造 2 界面有所改变,但基本上它和以前一样:

public interface EventService {
   @GET("/url/to/events/endpoint/")
   public Call<Event> get();
}

enqueue请求并定义Callback对象后,您还会在成功方法中获得一个Event对象,该对象将引用一个场地。以下是使用Retrofit 2 实现这些回调的方法(改版版本之间可能会稍有变化。我不会完全记住):

eventService.get().enqueue(new Callback<Event>() {
  @Override public void onResponse(Call<Event> call, Response<Event> response) {
    if (!response.isSuccessful()) {
      // Handle http error
      return;
    }

    Event event = response.body();
    Venue venue = event.getVenue();

    // do something with it
  }

  @Override public void onFailure(Call<Event> call, Throwable t) {
    // Handle error
  }
 });
}

此处eventService是由Retrofit.create(EventService.class)创建的对象。

再次改装位可能会根据您要使用的方法而改变。重要的是要了解如何从json响应映射到java对象,基本上你只需要在java对象中复制相同的json结构。希望它有所帮助。