Java 使用 Retrofit 访问 JSON 数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21815008/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using Retrofit to access JSON arrays
提问by K20GH
I thought I understood how to do this, but obviously not. I have my API from Flickr, which begins like so:
我以为我明白如何做到这一点,但显然不是。我有来自 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"
}
Now the information I need to get is from within the photo array, so what I have been trying to do is:
现在我需要获取的信息来自照片数组,所以我一直在尝试做的是:
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;
}
}
Very clear that I seem to be missing the point, however I am unsure of how to get the information..
很明显我似乎没有抓住重点,但是我不确定如何获取信息..
采纳答案by Brian Roach
A quick look at Retrofit's docs says it uses Gson to convert JSON to Java classes. This means you need a class hierarchy in Java that matches the JSON. Yours ... doesn't.
快速查看 Retrofit 的文档说它使用 Gson 将 JSON 转换为 Java 类。这意味着您需要一个与 JSON 匹配的 Java 类层次结构。你的……没有。
The returned JSON is an object with a single field "photos" that holds an object;
返回的 JSON 是一个带有单个字段“photos”的对象,该字段包含一个对象;
{ "photos" : { ... } }
So, your top level class would be a Java class with a single field:
因此,您的顶级类将是具有单个字段的 Java 类:
public class PhotosResponse {
private Photos photos;
// getter/setter
}
And that Photos
type would be another class that matches the JSON for the object that field contains:
该Photos
类型将是与字段包含的对象的 JSON 匹配的另一个类:
{ "page":1, "pages":10, ... }
So you'd have:
所以你会有:
public class Photos {
private int page;
private int pages;
private int perpage'
private int total;
private List<Photo> photo;
// getters / setters
}
And then you'd create a Photo
class to match the structure of the object in that inner array. Gson will then map the returned JSON appropriately.
然后您将创建一个Photo
类来匹配该内部数组中对象的结构。然后 Gson 将适当地映射返回的 JSON。
回答by LaSombra
I would suggest using http://www.jsonschema2pojo.org. You can paste your JSON and it will generate the POJOs for you.
我建议使用http://www.jsonschema2pojo.org。您可以粘贴您的 JSON,它会为您生成 POJO。
That should do the trick.
这应该够了吧。
回答by Gomino
You should be able to directly access the com.google.gson.JsonObject from Retrofit, and access whatever field you would like. So if you are only interested in the Photo array something like this should works:
您应该能够从 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;
}
}
And when you actually call the service just run the JsonObject to get what you want:
当您实际调用该服务时,只需运行 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());
Of course all the sanity check are left to you.
当然,所有的健全性检查都留给你。
回答by FOMDeveloper
The accepted answer is correct but it requires building a PhotoResponse class which only has one object in it. This the following solution, we only need to create the Photos class and some sterilization.
接受的答案是正确的,但它需要构建一个只有一个对象的 PhotoResponse 类。这是下面的解决方案,我们只需要创建Photos类和一些杀菌。
We create a JsonDeserializer:
我们创建一个 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);
}
}
Now we create our custom gson object to Retrofit's RestAdapter:
现在我们为 Retrofit 的 RestAdapter 创建我们的自定义 gson 对象:
Gson gson = new GsonBuilder()
.registerTypeAdapter(Photos.class, new PhotosDeserializer())
.create();
And then we set the converter in the retrofit adapter:
然后我们在改造适配器中设置转换器:
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(ArtService.ENDPOINT)
.setConverter(new GsonConverter(gson))
.build();
And the interface would look like this:
界面看起来像这样:
@GET("/?method="+METHOD_GET_RECENT+"&api_key="+API_KEY+"&format=json&nojsoncallback=1&extras="+EXTRAS_URL)
public void getPhotos(Callback<Photos> response);
This way we get the Photos object without having to create PhotosResponse class. We can use it like this:
这样我们就可以得到 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) {
}
});
回答by Vid
As already few answers are above which you can use. But as per my view use this. Make a photo class with all the variables given in photos object and create getter setter of all and also create a class of photo with will hold the list of photos and also create getter setter of this list in side the Photos class. Below is the code given.
因为上面已经很少有答案可以使用了。但根据我的观点,使用这个。使用照片对象中给定的所有变量创建一个照片类,并创建所有的 getter setter 并创建一个 photo 类,将保存照片列表,并在 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.
}