我对服务器的响应是不同类型的JSON对象的列表,这取决于每个响应的“类型”。我为每种响应类型都有不同的bean。可以使用Retrofit为列表中的每个响应(JSON对象)使用适当的Bean类吗(JSON数组)?
{
"cards": [2]
0: {
"type": "A"
"ID": 24
"author_name": "ari"
"title": "BB"
"permalink": ""
"created_date": "2015-12-18 17:17:00"
"post_date": "Dec 18 2015"
"thumbnail": ""
"summary": "Stars"
"thumbSmall": "100.jpg"
"androidXL": "500.jpg"
}-
1: {
"type": "B"
"_id": "3290"
"read_count": 0
"categories": [1]
0: "abc"
"title": "New"
"isSticky": false
"section": [0]
"author": "zzz"
"india": false
"update_time": 1450415789694
"summary": "Social"
"scoreId": "nz"
"isActive": true
"image": ""
"timestamp": 1450385165210
"events": [1]
0: "nz"
"teams": [0]
"slug": "new"
"isDeleted": false
"score_str": "SL"
}
}
作为一种解决方法,我创建了一个新的Bean类,包含所有可能的字段,每个JSON对象几乎有一半的字段为空。
有没有更好的方法呢?
答案 0 :(得分:1)
您可以创建一个超类,其中包含所有类型的通用数据并对其进行扩展:
public abstract class SuperItem {
public enum Type {
@SerializedName("A")
TYPEA(1),
@SerializedName("B")
TYPEB(2);
Type(final int value) {
this.value = value;
}
public static Type fromInteger(int i) {
switch (i) {
case 1:
return TYPEA;
case 2:
return TYPEB;
default:
Log.d("SuperItem", "No existing type for integer: " + i);
return null;
}
}
}
}
@SerializedName("type") private Type type;
}
public class AItem extends SuperItem {
}
public class BItem extends SuperItem {
}
默认情况下,Retrofit依赖于GSON进行JSON反序列化。您需要为您的实现创建自定义Gson反序列化器并将其设置为您的RestAdapter:
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(SuperItem.class, new SuperItemDeserializer());
Gson gson = builder.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
您的自定义反序列化器可能如下所示:
public class SuperItemDeserializer implements JsonDeserializer<SuperItem> {
@Override
public SuperItem deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
Gson gson = new Gson();
SuperItem item = null;
JsonObject rootObject = json.getAsJsonObject();
int typeInt = rootObject.get("type").getAsInt();
SuperItem.Type type = SuperItem.Type.fromInteger(typeInt);
switch (type) {
case TYPEA:
item = gson.fromJson(json, AItem.class);
break;
case TYPEB:
item = gson.fromJson(json, BItem.class);
break;
default:
Log.d("TAG", "Invalid type: " + typeInt);
}
return item;
}
}
希望示例中的命名不是太糟糕,你会得到这个想法:)