改型:使用GSON将JSON解析为多个Java对象

改型:使用GSON将JSON解析为多个Java对象,java,android,json,gson,retrofit,Java,Android,Json,Gson,Retrofit,我正在尝试创建照片对象的照片阵列列表。我想将Photo类与Photos类分开,因为它变得不可读。问题是我再也不能得到任何数据了 值得注意的是,当我将Photo类嵌套在Photos类中时,这是有效的,如下所示: public class Photos { @Expose private int page; @Expose private int pages; @Expose private int perpage; @Expose private String t

我正在尝试创建照片对象的照片阵列列表。我想将Photo类与Photos类分开,因为它变得不可读。问题是我再也不能得到任何数据了

值得注意的是,当我将Photo类嵌套在Photos类中时,这是有效的,如下所示:

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;
} 
如何分离这些类并仍然获得arrayList作为响应?我想将它们分开,因为我计划在每个类上使用Parcelable,在使用内部类时,我需要跨越一些障碍。任何指导都将不胜感激!谢谢

编辑:以下是JSON负载:

{ "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. upbound@upbound.net || 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" }

当使用改型和GSON时,没有办法将您的响应“分离”到不同的类中,您必须稍后自己进行。接收包含所有信息的大对象,然后将其展开到所需的类中


在我做的一个项目中,我有一个带有包装类的特定包,可以从改造中获得响应,然后我会手动将它映射到我实际需要的对象。希望有帮助。

事实证明,我在命名约定上犯了一个错误:

@Expose private ArrayList<Photo> mPhotos = new ArrayList<Photo>();
@Expose private ArrayList mPhotos=new ArrayList();
我在arrayList中将photo重命名为mPhotos,但忘记了GSON需要JSON字段的确切名称(最初是photo)。我将其改回“photo”,现在arrayList将填充到我的Photos对象上

我需要向自己强调,所有字段都必须符合JSON命名约定


谢谢。

您应该定义自己的TypeAdapter。不要仅仅因为API响应与您的POJO不匹配就创建Java对象。老实说,我发现创建包装类比编写自定义适配器更容易。这是您必须进行的调用。创建包装类会增加代码的复杂性和效率,但编写自定义TypeAdapter最初需要花费更多的开发时间。会增加代码的复杂性和效率吗?告诉我更多关于代码复杂性的信息:这是你自己说的。这是包装纸。您并没有为代码的用例创建理想的Java对象,因为您正在使它适合JSON负载。效率低下:Java对象不是廉价的分配。如果你真的只需要一个Java对象来定义你的数据,那么当你把它分成三个对象并扩展到数千个对象时,这会很糟糕。你能发布你想要反序列化的JSON(一个示例体)吗?我不太清楚你在问什么。你是说当你删除你的内部嵌套类时,你认为Gson停止了正确的反序列化吗?没错。它以前是工作的(如上面带有嵌套photo的photos类中所述),但是我将photo类移出到它自己的类中,它停止了工作。这可能是一个教育问题,另一个问题。Gson并不关心它是否是一个内部类。很抱歉…可能是的重复项,或者您可以使用SerializedName批注来根据需要命名字段。
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;
    }
}
{ "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. upbound@upbound.net || 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" }
@Expose private ArrayList<Photo> mPhotos = new ArrayList<Photo>();