Futureproof
Futureproof

Reputation: 375

Retrofit: Parsing JSON to multiple Java objects using GSON

I'm trying to create an Photos ArrayList of Photo objects. I want to separate the Photo class from the Photos class because it's becoming unreadable. The problem is that I'm no longer getting any data back

It is worth noting that this WAS working when I had the Photo class nested in Photos class as follows:

public class Photos { 
    @Expose private int page;
    @Expose private int pages;
    @Expose private int perpage;
    @Expose private String total;
    @Expose private ArrayList<Photo> photo = new ArrayList<Photo>();

    //helpers 
    public ArrayList<Photo> getPhotos(){return photo;}
    public void setPhotos(ArrayList<Photo> photos){this.photo = photos;}

//want to put this in it's own class
public class Photo { 
    //helpers 
    @Override 
    public String toString(){
        return title;
    } 
    public String getUrl(){return url_s;}

    //GSON fields 
    @Expose private String id;
    @Expose private String owner;
    @Expose private String secret;
    @Expose private String server;
    @Expose private int farm;
    @Expose private String title;
    @Expose private int ispublic;
    @Expose private int isfriend;
    @Expose private int isfamily;
    @Expose private String url_s;
} 

}

Retrofit:

 new Callback<PhotosResponse>() {
                    @Override
                    public void success(PhotosResponse photosResponse, Response response) {
                    bus.post(new ImagesReceivedEvent(photosResponse.getPhotosObject().getPhotos()));
                }

The parameters matched the JSON exactly and I received an arraylist through the following response:

public class ImagesReceivedEvent {

    private ArrayList<Photo> result;

    public ImagesReceivedEvent(ArrayList<Photo> result){
        Log.i(TAG, "arraylist for presenter");
        this.result = result;
    }

    public ArrayList<Photo> getResult(){return result;}
}

This is where the response was received, but no longer:

public class PhotosResponse {

    @Expose private Photos photos;
    @Expose private String stat;

    public Photos getPhotosObject(){return photos;}

    public void setPhotosObject(Photos photos) {
        this.photos = photos;
    }

    public String getStat() {
        return stat;
    }

    public void setStat(String stat) {
        this.stat = stat;
    }
}

How can I separate these classes and still get the arrayList as a response? I want to separate them because I plan on using Parcelable on each class there are some hurdles I'd need to jump over when having the inner class. Any guidance would be much appreciated! Thanks.

Edit: Here is the JSON payload:

{ "photos": { "page": 1, "pages": 10, "perpage": 100, "total": "1000", 
"photo": [
  { "id": "18473086614", "owner": "130897025@N07", "secret": "b3c684c356", "server": "259", "farm": 1, "title": "My travels circa 2013. Summer days on #charlesbridge #charlesbridgeprague #prauge. [email protected] || 718-754-5850 #photographer #photography #canonphotography #canon #canondslr #canon600d #dslr #600d #travelphotography #europe #upboundonline #canonre", "ispublic": 1, "isfriend": 0, "isfamily": 0 },
  { "id": "18473090744", "owner": "131790787@N07", "secret": "2734055852", "server": "3705", "farm": 4, "title": "Untitled", "ispublic": 1, "isfriend": 0, "isfamily": 0 },
  { "id": "18473091934", "owner": "61308696@N00", "secret": "b40dbfcf15", "server": "401", "farm": 1, "title": "Climbing Acatenango", "ispublic": 1, "isfriend": 0, "isfamily": 0 },
  { "id": "18473092714", "owner": "39055811@N08", "secret": "e51f5a183b", "server": "3936", "farm": 4, "title": "DSCF1735.jpg", "ispublic": 1, "isfriend": 0, "isfamily": 0 }
] }, "stat": "ok" }

Upvotes: 1

Views: 1662

Answers (2)

Futureproof
Futureproof

Reputation: 375

It turns out that I made a mistake on the naming convention:

@Expose private ArrayList<Photo> mPhotos = new ArrayList<Photo>();

I had renamed photo to mPhotos on the arrayList but forgot that GSON needs the EXACT names of the JSON fields (Which is originally photo). I changed it back to "photo" and now the arrayList populates on my Photos object.

I need to emphasize to myself that all fields MUST match the JSON naming convention.

Thanks.

Upvotes: 1

Teo Inke
Teo Inke

Reputation: 5986

When using Retrofit and GSON there's no way to "separate" your response into different classes, you must later do it yourself. Receive your big object with all the info, then unwrap it to the needed classes.

On a project I did I had a specific package with Wrapper classes to get responses from Retrofit, then later I'd manually map it to the Objects I actually needed. Hope it helps.

Upvotes: 0

Related Questions