Вопрос

I thought I understood how to do this, but obviously not. I have my API from Flickr, which begins like so:

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..

Это было полезно?

Решение 2

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.

The returned JSON is an object with a single field "photos" that holds an object;

{ "photos" : { ... } }

So, your top level class would be a Java class with a single field:

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:

{ "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.

Другие советы

I would suggest using http://www.jsonschema2pojo.org. You can paste your JSON and it will generate the POJOs for you.

That should do the trick.

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.

We create a 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:

    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:

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) {


    }
});

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:

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 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.

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.

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.
    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top