我以为我明白了怎么做,但显然不是。我有来自Flickr的API,它的开头是这样的:
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;
}
}
很明显我似乎忽略了这一点,但我不确定如何获取信息..
答案 0 :(得分:47)
我建议使用http://www.jsonschema2pojo.org。您可以粘贴JSON,它将为您生成POJO。
这应该可以解决问题。
答案 1 :(得分:42)
快速浏览一下Retrofit的文档说它使用Gson将JSON转换为Java类。这意味着您需要Java中与JSON匹配的类层次结构。你的......没有。
返回的JSON是一个对象,其中包含一个包含对象的“photos”字段;
{ "photos" : { ... } }
因此,您的顶级类将是具有单个字段的Java类:
public class PhotosResponse {
private Photos photos;
// getter/setter
}
而Photos
类型将是另一个与该字段包含的对象的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
}
然后你创建一个Photo
类来匹配该内部数组中对象的结构。然后Gson将适当地映射返回的JSON。
答案 2 :(得分:10)
接受的答案是正确的,但它需要构建一个只有一个对象的PhotoResponse类。这个解决方案,我们只需要创建Photos类和一些灭菌。
我们创建一个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);
}
}
现在我们为Retrofit的RestAdapter创建我们的自定义gson对象:
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对象而无需创建PhotosResponse类。我们可以像这样使用它:
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) {
}
});
答案 3 :(得分:2)
您应该能够直接从Retrofit访问com.google.gson.JsonObject,并访问您想要的任何字段。 因此,如果您只对Photo数组感兴趣,那么这样的事情应该有效:
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());
当然所有的理智检查都留给你。
答案 4 :(得分:0)
由于您已经可以使用的答案很少。但根据我的观点,请使用此功能。 制作一个照片类,其中包含照片对象中给出的所有变量,并创建所有的getter setter,并创建一个照片类,其中包含照片列表,并在Photos类的旁边创建此列表的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.
}