Sie würden einen benutzerdefinierten Deserializer schreiben, der das eingebettete Objekt zurückgibt.
Angenommen, Ihr JSON lautet:
{
"status":"OK",
"reason":"some reason",
"content" :
{
"foo": 123,
"bar": "some value"
}
}
Sie hätten dann ein Content
POJO:
class Content
{
public int foo;
public String bar;
}
Dann schreiben Sie einen Deserializer:
class MyDeserializer implements JsonDeserializer<Content>
{
@Override
public Content deserialize(JsonElement je, Type type, JsonDeserializationContext jdc)
throws JsonParseException
{
// Get the "content" element from the parsed JSON
JsonElement content = je.getAsJsonObject().get("content");
// Deserialize it. You use a new instance of Gson to avoid infinite recursion
// to this deserializer
return new Gson().fromJson(content, Content.class);
}
}
Wenn Sie nun einen Gson
mit GsonBuilder
erstellen und den Deserializer registrieren:
Gson gson =
new GsonBuilder()
.registerTypeAdapter(Content.class, new MyDeserializer())
.create();
Sie können Ihren JSON direkt auf Folgendes deserialisieren Content
:
Content c = gson.fromJson(myJson, Content.class);
Bearbeiten, um aus Kommentaren hinzuzufügen:
Wenn Sie verschiedene Arten von Nachrichten haben, aber alle das Feld "Inhalt" haben, können Sie den Deserializer generisch machen, indem Sie Folgendes tun:
class MyDeserializer<T> implements JsonDeserializer<T>
{
@Override
public T deserialize(JsonElement je, Type type, JsonDeserializationContext jdc)
throws JsonParseException
{
// Get the "content" element from the parsed JSON
JsonElement content = je.getAsJsonObject().get("content");
// Deserialize it. You use a new instance of Gson to avoid infinite recursion
// to this deserializer
return new Gson().fromJson(content, type);
}
}
Sie müssen nur eine Instanz für jeden Ihrer Typen registrieren:
Gson gson =
new GsonBuilder()
.registerTypeAdapter(Content.class, new MyDeserializer<Content>())
.registerTypeAdapter(DiffContent.class, new MyDeserializer<DiffContent>())
.create();
Wenn Sie .fromJson()
den Typ aufrufen, wird er in den Deserializer übertragen, sodass er für alle Ihre Typen funktionieren sollte.
Und schließlich beim Erstellen einer Retrofit-Instanz:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();