3 回答

TA貢獻(xiàn)1828條經(jīng)驗 獲得超3個贊
如果在某些情況下相同的端點返回不同的類型,我建議將該部分包裝在一個對象中并使用反序列化器檢查類型并相應(yīng)地分配。你可以這樣做:
public Parent serialize(String jsonString) {
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(WrappedChild.class, new ChildDeserializer());
Gson gson = builder.create();
return gson.fromJson(jsonString, Parent.class);
}
class Parent {
public List<WrappedChild> children;
}
class ObjectChild {
public String body;
}
class WrappedChild {
public ObjectChild objectChild;
public String stringChild;
}
class ChildDeserializer implements JsonDeserializer<WrappedChild> {
private Gson gson = new Gson();
@Override
public WrappedChild deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
if (json != null) {
if (json.isJsonObject()) {
WrappedChild result = new WrappedChild();
result.objectChild = gson.fromJson(json, ObjectChild.class);
return result;
} else if (json.isJsonPrimitive()) {
WrappedChild result = new WrappedChild();
result.stringChild = json.getAsString();
return result;
}
}
return null; // Or throw new Exception("Unknown child type");
}
}
如果您正在使用改造,只需GsonConverterFactory.create在創(chuàng)建服務(wù)時將構(gòu)建器創(chuàng)建的 Gson作為參數(shù)傳遞給。

TA貢獻(xiàn)1821條經(jīng)驗 獲得超5個贊
您應(yīng)該仔細(xì)研究Emre Eran 的答案,因為這樣您就可以完全控制反序列化。我將給出另一種方法,在某些情況下可能需要較少的努力。它基于Gson反序列化的“基本智能” 。
如果您聲明包含以下內(nèi)容的children類:
public class Parent {
Collection<?> children;
}
Gson盡量“猜測”對象類型。如果它面對一個簡單的字符串,它將被反序列化為String. 如果它像第一個Json示例中那樣面對數(shù)據(jù),它將反序列化為樹的com.google.gson.internal.LinkedTreeMap一個Java版本Json。
因此,根據(jù)data第一個示例中對象的復(fù)雜程度以及您總體上如何使用結(jié)果,您可能不需要編寫自定義反序列化器(無論如何最終可能是更好的解決方案)。

TA貢獻(xiàn)1796條經(jīng)驗 獲得超4個贊
對不起,遲到的答案,感謝您帶領(lǐng)我走向正確的方向 Emre!
我最終讓 GsonBuilder 使用自定義方法 getGsonAdaptedData。
在后臺線程中檢索 JSON 響應(yīng)后:
...
Gson gson = new GsonBuilder().registerTypeAdapter(Data.class, (JsonDeserializer<Data>) (arg0, arg1, arg2) -> {
JsonObject dataJsonObject = arg0.getAsJsonObject();
Data data = new Gson().fromJson(dataJsonObject, Data.class);
return RedditUtils.getGsonAdaptedData(dataJsonObject.get("children").getAsJsonArray(), data);
}).create();
final Feed responseSubredditFeed = gson.fromJson(jsonString, Feed.class);
...
RedditUtils.getGsonAdaptedData
// JSON returned for Reddit comments can contain two types of arrays named "children"
// This method checks to see if we were given a Children array or String array
// JSON member "replies" is similar, and can be found in the Data of some Children
// If the method finds a nested "children" array, it recursively adapts its Data
public static Data getGsonAdaptedData(JsonArray childrenJsonArray, Data data) {
if (childrenJsonArray.size() > 0) {
Gson gson = new Gson();
if (childrenJsonArray.get(0).isJsonObject()) {
data.setChildrenList(gson.fromJson(childrenJsonArray,
new TypeToken<List<Children>>() {
}.getType()));
// Loops through every Data object in the array looking for children and replies
for (int i = 0; i < childrenJsonArray.size(); i++) {
JsonObject nestedDataJsonObject = childrenJsonArray.get(i).getAsJsonObject().get("data").getAsJsonObject();
if (nestedDataJsonObject.has("children")) {
getGsonAdaptedData(nestedDataJsonObject.get("children").getAsJsonArray(), data.getChildren().get(i).getData());
} else if (nestedDataJsonObject.has("replies") && nestedDataJsonObject.get("replies").isJsonObject()) {
data.getChildren().get(i).getData().setRepliesObject(gson.fromJson(nestedDataJsonObject.get("replies"),
new TypeToken<Replies>() {
}.getType()));
getGsonAdaptedData(nestedDataJsonObject.get("replies").getAsJsonObject().get("data").getAsJsonObject().get("children").getAsJsonArray(), data.getChildren().get(i).getData());
}
}
} else {
data.setRepliesList(gson.fromJson(childrenJsonArray,
new TypeToken<List<String>>() {
}.getType()));
}
}
return data;
}
添加回答
舉報