如何在GSON解析之前向对象添加自定义字段

时间:2016-08-21 06:52:34

标签: java android json gson retrofit

我有一种情况,当服务器返回团队中的玩家列表,但玩家对象不包含团队ID,我需要手动传递,或者在接收后走一个looper

我使用 Retrofit 2.1 Gson 2.7

我有一些Gson模型

public class SomeClass {

    @SerializedName("fieldFromJSON")
    private String mFieldFromJSON;
    private String mCustomField; //<= This field is not in response

    //... Empty constructor, getters and setters
}

和Retrofit界面

@GET("some/url")
Call<List<SomeClass>> getData(
        String customField //<= This I must put to all classes in customField
);

给出了这个回复

[
    {
        "fieldFromJSON":"something"
    }
    //, {...}, ...
]

是否可以创建List SomeClass并使用Retrofit和Gson将customField放到所有SomeClass类中?

2 个答案:

答案 0 :(得分:2)

  

服务器返回一个列表[...],但[...]对象不包含[...] id

以下是我能想到的一些选项(请原谅我不完整的改造代码)

选项1:循环改造结果。以迭代列表为代价,如果您绝对需要每个对象的变量引用,这是很好的。

final String id = "bla";

Call call = service.getData(id);
call.enqueue(new Callback<List<SomeClass>>() {

   public void onResponse(List<SomeClass> list) {
       for (SomeClass c : list) {
           c.setCustomField(id);
       }
   }

   // onError() {}
}

选项2:将字段映射到列表。你说你有一个团队中的玩家列表,你的API调用似乎通过ID获得这些团队。这很好,例如,当为所有球队获得所有球员并且您需要通过ID快速查找球队时。实质上,您正在缓存API团队查找。

final Map<String, ArrayList<SomeClass>> teamMap = new HashMap<>();

final String id = "bla";

Call call = service.getData(id);
call.enqueue(new Callback<List<SomeClass>>() {

   public void onResponse(List<SomeClass> list) {
       teamMap.put(id, list);
   }

   // onError() {}
}

选项3:重新构建服务器API以返回每个返回对象所需的请求字段。

答案 1 :(得分:0)

您可以为SomeClass创建构造函数,它不需要任何参数并在其中填充默认值。它将由Gson调用,除非json覆盖它们,否则这些默认值将保持不变

public class SomeClass {
    private int id;
    //... some other fields
    //and constructors

    public SomeClass(){
        this.id = -1; //default value for contructor
    }
}

您还可以查看custom instance creator