我从后端团队提供的API中获取数据。其中一个键data
有时包含JSONObject
,有时它包含JSONArray
。我正在使用GSON
来解析响应,因此会抛出异常。
我尝试了这个帖子中给出的解决方案,但它在我的情况下不起作用。 How to dynamically handle json response array/object using Gson
POJO(EntityDetailResponseV2):
package com.tf.eros.faythTv.objects.entityDetail;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.SerializedName;
import com.tf.eros.faythTv.objects.entityFeatured.EntityFeaturedResponse;
import com.tf.eros.faythTv.utils.ArrayAdapterFactory;
import java.util.List;
public class EntityDetailResponseV2 {
@SerializedName("results")
private Results results;
@SerializedName("success")
private boolean success;
public static EntityDetailResponseV2 getObject(String res) {
try {
Gson gson = new GsonBuilder().registerTypeAdapterFactory(new ArrayAdapterFactory()).create();
return gson.fromJson(res, EntityDetailResponseV2.class);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public Results getResults() {
return results;
}
public boolean isSuccess() {
return success;
}
public static class Results {
@SerializedName("id")
Integer entityID;
@SerializedName("name")
String entityName;
@SerializedName("description")
String entityDescription;
@SerializedName("image_url")
String entityImageURL;
@SerializedName("square_entity_url")
String entitySquareURL;
@SerializedName("slug")
String entitySlug;
@SerializedName("live")
boolean isEntityLive;
@SerializedName("twitter_username")
String twitterUserName;
@SerializedName("fb_username")
String fbUserName;
@SerializedName("featured")
private List<EntityFeaturedResponse> featured;
@SerializedName("collections")
List<Collections> collectionsList;
public Integer getEntityID() {
return entityID;
}
public String getEntityName() {
return entityName;
}
public String getEntityDescription() {
return entityDescription;
}
public String getEntityImageURL() {
return entityImageURL;
}
public String getEntitySquareURL() {
return entitySquareURL;
}
public String getEntitySlug() {
return entitySlug;
}
public boolean isEntityLive() {
return isEntityLive;
}
public String getTwitterUserName() {
return twitterUserName;
}
public String getFbUserName() {
return fbUserName;
}
public List<EntityFeaturedResponse> getFeatured() {
return featured;
}
public List<Collections> getCollectionsList() {
return collectionsList;
}
public static class Collections {
@SerializedName("type")
String type;
@SerializedName("type_id")
Integer typeID;
//Data sometimes contains JSON object and sometimes it contains JSON Array
@SerializedName("data")
List<Data> data;
public String getType() {
return type;
}
public Integer getTypeID() {
return typeID;
}
public List<Data> getData() {
return data;
}
public static class Data {
@SerializedName("view_all")
boolean viewAll;
@SerializedName("title")
String title;
public boolean isViewAll() {
return viewAll;
}
public String getTitle() {
return title;
}
}
}
}
}
ArrayAdapterFactory.java
public class ArrayAdapterFactory implements TypeAdapterFactory {
@SuppressWarnings({"unchecked"})
@Override
public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> type) {
ArrayAdapter typeAdapter = null;
try {
if (type.getRawType() == List.class) {
typeAdapter = new ArrayAdapter(
(Class) ((ParameterizedType) type.getType())
.getActualTypeArguments()[0]);
}
} catch (Exception e) {
e.printStackTrace();
}
return typeAdapter;
}
public class ArrayAdapter<T> extends TypeAdapter<List<T>> {
private Class<T> adapterClass;
public ArrayAdapter(Class<T> adapterClass) {
this.adapterClass = adapterClass;
}
public List<T> read(JsonReader reader) throws IOException {
List<T> list = new ArrayList<T>();
Gson gson = new Gson();
if (reader.peek() == JsonToken.BEGIN_OBJECT) {
T inning = (T) gson.fromJson(reader, adapterClass);
list.add(inning);
} else if (reader.peek() == JsonToken.BEGIN_ARRAY) {
reader.beginArray();
while (reader.hasNext()) {
//read(reader);
T inning = (T) gson.fromJson(reader, adapterClass);
list.add(inning);
}
reader.endArray();
} else {
reader.skipValue();
}
return list;
}
public void write(JsonWriter writer, List<T> value) throws IOException {
}
}
}
由于完整的API响应非常大,我提供了.json文件的链接。 https://drive.google.com/open?id=1RMOiM7UjOwR-5b0Ik7ymy65ZOhc8I8hY
更新
我尝试了下面提到的解决方案但仍然是,DataType1和DataType2都是空的。虽然我不再获得GSON
例外。
public class EntityDetailResponseV2 {
@SerializedName("results")
private Results results;
@SerializedName("success")
private boolean success;
public static EntityDetailResponseV2 getObject(String res) {
try {
Gson gson = new GsonBuilder().registerTypeAdapter(Collections.class, new Results.Collections.CollectionItemDeserializer()).create();
return gson.fromJson(res, EntityDetailResponseV2.class);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public Results getResults() {
return results;
}
public boolean isSuccess() {
return success;
}
public static class Results {
@SerializedName("id")
Integer entityID;
@SerializedName("name")
String entityName;
@SerializedName("description")
String entityDescription;
@SerializedName("image_url")
String entityImageURL;
@SerializedName("square_entity_url")
String entitySquareURL;
@SerializedName("slug")
String entitySlug;
@SerializedName("live")
boolean isEntityLive;
@SerializedName("twitter_username")
String twitterUserName;
@SerializedName("fb_username")
String fbUserName;
@SerializedName("featured")
private List<EntityFeaturedResponse> featured;
@SerializedName("collections")
List<Collections> collectionsList;
public Integer getEntityID() {
return entityID;
}
public String getEntityName() {
return entityName;
}
public String getEntityDescription() {
return entityDescription;
}
public String getEntityImageURL() {
return entityImageURL;
}
public String getEntitySquareURL() {
return entitySquareURL;
}
public String getEntitySlug() {
return entitySlug;
}
public boolean isEntityLive() {
return isEntityLive;
}
public String getTwitterUserName() {
return twitterUserName;
}
public String getFbUserName() {
return fbUserName;
}
public List<EntityFeaturedResponse> getFeatured() {
return featured;
}
public List<Collections> getCollectionsList() {
return collectionsList;
}
public static class Collections {
@SerializedName("type")
String type;
@SerializedName("order")
Integer order;
@SerializedName("type_id")
Integer typeId;
DataType1 dataType1;
List<DataType2> dataType2;
public String getType() {
return type;
}
public Integer getOrder() {
return order;
}
public Integer getTypeId() {
return typeId;
}
public DataType1 getDataType1() {
return dataType1;
}
public List<DataType2> getDataType2() {
return dataType2;
}
public static class CollectionItemDeserializer implements JsonDeserializer<Collections> {
@Override
public Collections deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
Collections collectionItem = new Gson().fromJson(json, Collections.class);
JsonObject jsonObject = json.getAsJsonObject();
if (collectionItem.getType() != null) {
JsonElement element = jsonObject.get("data");
switch (collectionItem.getTypeId()) {
case AppConstants.ENTITY_SHOP:
case AppConstants.ENTITY_MEDIA_COLLECTION:
case AppConstants.ENTITY_ECOM_COLLECTION:
case AppConstants.ENTITY_BANNER:
collectionItem.dataType1 = new Gson().fromJson(element, DataType1.class);
break;
case AppConstants.ENTITY_TOP_AUDIOS:
case AppConstants.ENTITY_TOP_VIDEOS:
case AppConstants.ENTITY_LATEST_VIDEOS:
case AppConstants.ENTITY_TOP_PLAYLISTS:
case AppConstants.ENTITY_WALLPAPERS:
case AppConstants.ENTITY_QUOTATIONS:
List<DataType2> values = new Gson().fromJson(element, new TypeToken<ArrayList<DataType2>>() {}.getType());
collectionItem.dataType2 = values;
break;
}
}
return collectionItem;
}
}
public static class DataType1 {
@SerializedName("view_all")
boolean viewAll;
public boolean isViewAll() {
return viewAll;
}
}
public static class DataType2 {
@SerializedName("view_all")
boolean viewAll;
public boolean isViewAll() {
return viewAll;
}
}
}
}
}
答案 0 :(得分:1)
您需要使用自定义JsonDeserializer。这是解决方案:
new
DataType1,DataType2等是不同响应的各个类。
另外,添加此行以使用gson注册自定义反序列化器
new