使用Retrofit来访问JSON数组
我以为我明白如何做到这一点,但显然不是。 我有我的API从Flickr,开始像这样:
jsonFlickrApi({ "photos":{ "page":1, "pages":10, "perpage":100, "total":1000, "photo":[ { "id":"12567883725", "owner":"74574845@N05", "secret":"a7431762dd", "server":"7458", "farm":8, "title":"", "ispublic":1, "isfriend":0, "isfamily":0, "url_l":"http:\/\/farm8.staticflickr.com\/7458\/12567883725_a7431762dd_b.jpg", "height_l":"683", "width_l":"1024" }
现在我需要从照片数组中获得的信息,所以我一直在试图做的是:
interface ArtService { @GET("/services/rest/?method=flickr.photos.getRecent&extras=url_l&owner_name&format=json") PhotosResponse getPhotos(); public class PhotosResponse { Photos photos; } public class Photos { List<Arraz> photo; } public class Arraz { int id; String title; String owner; String url_l; } }
很明显,我似乎错过了这一点,但我不确定如何获得信息..
快速查看Retrofit的文档说,它使用Gson将JSON转换为Java类。 这意味着您需要在Java中匹配JSON的类层次结构。 你的…不。
返回的JSON是一个包含单个字段“photos”的对象,该字段包含一个对象;
{ "photos" : { ... } }
因此,您的顶级类将是一个带有单个字段的Java类:
public class PhotosResponse { private Photos photos; // getter/setter }
而且这个Photos
types是另外一个与该字段包含的对象匹配的JSON类:
{ "page":1, "pages":10, ... }
所以你会有:
public class Photos { private int page; private int pages; private int perpage' private int total; private List<Photo> photo; // getters / setters }
然后,您将创build一个Photo
类来匹配该内部数组中的对象的结构。 然后Gson会适当地映射返回的JSON。
我会build议使用http://www.jsonschema2pojo.org 。 你可以粘贴你的JSON,它会为你生成POJO。
这应该够了吧。
接受的答案是正确的,但它需要build立一个只有一个对象的PhotoResponse类。 这下面的解决scheme,我们只需要创buildPhotos类和一些消毒。
我们创build一个JsonDeserializer:
class PhotosDeserializer implements JsonDeserializer<Photos> { @Override public Photos deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonElement content = json.getAsJsonObject().get("photos"); return new Gson().fromJson(content, Photos.class); } }
现在我们创build我们自定义的gson对象来改造RestAdapter:
Gson gson = new GsonBuilder() .registerTypeAdapter(Photos.class, new PhotosDeserializer()) .create();
然后我们将转换器设置在改造适配器中:
RestAdapter restAdapter = new RestAdapter.Builder() .setEndpoint(ArtService.ENDPOINT) .setConverter(new GsonConverter(gson)) .build();
界面如下所示:
@GET("/?method="+METHOD_GET_RECENT+"&api_key="+API_KEY+"&format=json&nojsoncallback=1&extras="+EXTRAS_URL) public void getPhotos(Callback<Photos> response);
这样我们就可以获得Photos对象而不必创buildPhotosResponse类。 我们可以这样使用它:
ArtService artService = restAdapter.create(ArtService.class); artService.getPhotos(new Callback<Photos>() { @Override public void success(Photos photos, Response response) { // Array of photos accessing by photos.photo } @Override public void failure(RetrofitError error) { } });
您应该可以直接从Retrofit访问com.google.gson.JsonObject,并访问您想要的任何字段。 所以如果你只对Photoarrays感兴趣,应该这样做:
interface ArtService { @GET("/services/rest/?method=flickr.photos.getRecent&extras=url_l&owner_name&format=json") JsonObject getPhotos(); public class Photo { int id; String title; String owner; String url_l; } }
而当你真正调用服务时,只需运行JsonObject即可获得你想要的:
JsonObject json = mRestClient.getArtService().getPhotos(); List<ArtService.Photo> photos = new Gson().fromJson(json.getAsJsonObject("photos").get("photo").toString(), new TypeToken<List<ArtService.Photo>>() {}.getType());
当然,所有的理智检查都留给你。
因为已经很less有答案可以使用。 但按照我的观点使用这个。 使用照片对象中给出的所有variables创build一个照片类,并创build所有的getter setter,并创build一个照片类,将保存照片列表,并在Photo类中创build此列表的getter setter。 以下是给出的代码。
public static class Photos { @JsonProperty("page") private double page; @JsonProperty("pages") private double pages; @JsonProperty("perpage") private double perpage; @JsonProperty("total") private double total; @JsonProperty("photo") private List<Photo> photo; public double getPage() { return page; } public void setPage(double page) { this.page = page; } public double getPages() { return pages; } public void setPages(double pages) { this.pages = pages; } public double getPerpage() { return perpage; } public void setPerpage(double perpage) { this.perpage = perpage; } public double getTotal() { return total; } public void setTotal(double total) { this.total = total; } } public static class Photo { // refer first class and declare all variable of photo array and generate getter setter. }